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的博客

    原文作者:lange0x0
    原文地址: https://www.jianshu.com/p/9d4e39a83a74
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞