1. 程式人生 > >RxJava執行緒切換代替Thread和Handler

RxJava執行緒切換代替Thread和Handler

在我們的日常開發中,我們可能會經常涉及到執行緒的切換,比如:需要在子執行緒中載入資料庫中的資料,一般情況下,我們會這樣做:

 new Thread(new Runnable() {
            @Override
            public void run() {
                //do something
            }
        }).start();

高效一點的會用執行緒池來實現。但是有一種情況下是很麻煩的-子執行緒和主執行緒有執行順序或者有互動的時候,這時候我們一般藉助Handler機制來實現或者呼叫Activity的runOnUiThread(new Runnable(){})

。但是今天我們來介紹一種利用RxJava實現的主執行緒、子執行緒快速切換的方法。

子執行緒執行

定義一個子執行緒執行的任務介面

public interface IOTask<T> {
    void doOnIOThread();
}

在RxScheduler中定義一個在doOnIOThread方法,利用observeOn來切換執行的執行緒

 public static <T> void doOnIOThread(final IOTask<T> task) {
        Observable.just(task)
               .observeOn(Schedulers.io())
                .subscribe(new
Action1<IOTask<T>>() { @Override public void call(IOTask<T> tioTask) { tioTask.doOnIOThread(); } }, new Action1<Throwable>() { @Override public
void call(Throwable throwable) { throwable.printStackTrace(); } }); }

主執行緒執行

同理,如果想在主執行緒中執行時,定義一個任務類介面UITask

public interface UITask<T> {
    void doOnUIThread();
}

在RxScheduler中定義一個在doOnUiThread方法:

 public static <T> void doOnUiThread(final UITask<T> task) {
        Observable.just(task)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<UITask<T>>() {
                    @Override
                    public void call(UITask<T> tuiTask) {
                        task.doOnUIThread();
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        throwable.printStackTrace();
                    }
                });
    }

主執行緒和子執行緒有互動執行

這種情況比較複雜些,一般是在子執行緒中執行完後,需要在主執行緒中執行一些程式碼,有著一定的時間順序關係。但是無論怎麼變化,RxJava都能輕鬆搞定~~

定義一個任務抽象類Task,其中T表示子執行緒和主執行緒需要呼叫的物件

public abstract class Task<T> {
    private T t;

    public Task(T t) {
        this.t = t;
    }

    public void setT(T t) {
        this.t = t;
    }

    public T getT() {
        return t;
    }

    public abstract void doOnUIThread();

    public abstract void doOnIOThread();
}

RxScheduler類中定義一個doTask方法:

  public static <T> void doTask(final Task<T> task) {
        Observable.create(new Observable.OnSubscribe<T>() {
            @Override
            public void call(Subscriber<? super T> subscriber) {
                task.doOnIOThread();
                subscriber.onNext(task.getT());
                subscriber.onCompleted();
            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<T>() {
                    @Override
                    public void call(T t) {
                        task.doOnUIThread();
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        throwable.printStackTrace();
                    }
                });
    }

原理很簡單,如果你熟悉RxJava的使用的話~

測試程式碼

RxScheduler.doOnIOThread(new IOTask<Void>() {
            @Override
            public void doOnIOThread() {

                System.out.println("doOnIOThread->" + Thread.currentThread().getName());
            }
        });

        RxScheduler.doOnUiThread(new UITask<Void>() {
            @Override
            public void doOnUIThread() {

                System.out.println("doOnUIThread->" + Thread.currentThread().getName());
            }
        });
        final List<String> mData = new ArrayList<>();
        RxScheduler.doTask(new Task<List<String>>(mData) {
            @Override
            public void doOnUIThread() {
                for (String i : mData) {
                    System.out.println(Thread.currentThread().getName() + "-->" + i);
                }
            }

            @Override
            public void doOnIOThread() {
                mData.add("java");
                mData.add("hello");
                System.out.println(Thread.currentThread().getName() + "-->" + mData.size());
            }
        });

結果如下:

shiyiliang.me.langelibarysample I/System.out: doOnIOThread->RxIoScheduler-2
shiyiliang.me.langelibarysample I/System.out: RxIoScheduler-2-->2
shiyiliang.me.langelibarysample I/System.out: doOnIOThread->main
shiyiliang.me.langelibarysample I/System.out: main-->java
shiyiliang.me.langelibarysample I/System.out: main-->hello

是不是比使用Thread或者執行緒池方便多了,雖然內部底層原理類似,但是後者使用起來就方便多了。

如果想閱讀其他的文章,可以訪問我的個人部落格Lange的部落格