RxJava线程切换代替Thread和Handler

xiaoxiao2021-02-27  261

在我们的日常开发中,我们可能会经常涉及到线程的切换,比如:需要在子线程中加载数据库中的数据,一般情况下,我们会这样做:

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

转载请注明原文地址: https://www.6miu.com/read-7509.html

最新回复(0)