在我們的日常開(kāi)發(fā)中宿亡,我們可能會(huì)經(jīng)常涉及到線程的切換凑耻,比如:需要在子線程中加載數(shù)據(jù)庫(kù)中的數(shù)據(jù),一般情況下攒钳,我們會(huì)這樣做:
new Thread(new Runnable() {
@Override
public void run() {
//do something
}
}).start();
高效一點(diǎn)的會(huì)用線程池來(lái)實(shí)現(xiàn)帮孔。但是有一種情況下是很麻煩的-子線程和主線程有執(zhí)行順序或者有交互的時(shí)候,這時(shí)候我們一般借助Handler機(jī)制來(lái)實(shí)現(xiàn)或者調(diào)用Activity的runOnUiThread(new Runnable(){})
不撑。但是今天我們來(lái)介紹一種利用RxJava實(shí)現(xiàn)的主線程文兢、子線程快速切換的方法。
子線程執(zhí)行
定義一個(gè)子線程執(zhí)行的任務(wù)接口
public interface IOTask<T> {
void doOnIOThread();
}
在RxScheduler中定義一個(gè)在doOnIOThread
方法燎孟,利用observeOn
來(lái)切換執(zhí)行的線程
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();
}
});
}
主線程執(zhí)行
同理禽作,如果想在主線程中執(zhí)行時(shí)尸昧,定義一個(gè)任務(wù)類接口UITask
public interface UITask<T> {
void doOnUIThread();
}
在RxScheduler中定義一個(gè)在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();
}
});
}
主線程和子線程有交互執(zhí)行
這種情況比較復(fù)雜些揩页,一般是在子線程中執(zhí)行完后,需要在主線程中執(zhí)行一些代碼烹俗,有著一定的時(shí)間順序關(guān)系爆侣。但是無(wú)論怎么變化,RxJava都能輕松搞定~~
定義一個(gè)任務(wù)抽象類Task
幢妄,其中T
表示子線程和主線程需要調(diào)用的對(duì)象
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
類中定義一個(gè)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();
}
});
}
原理很簡(jiǎn)單兔仰,如果你熟悉RxJava的使用的話~
測(cè)試代碼
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());
}
});
結(jié)果如下:
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或者線程池方便多了,雖然內(nèi)部底層原理類似蕉鸳,但是后者使用起來(lái)就方便多了乎赴。
如果想閱讀其他的文章忍法,可以訪問(wèn)我的個(gè)人博客Lange的博客