RxJava線程切換代替Thread和Handler

在我們的日常開(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的博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市榕吼,隨后出現(xiàn)的幾起案子饿序,更是在濱河造成了極大的恐慌,老刑警劉巖羹蚣,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件原探,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡顽素,警方通過(guò)查閱死者的電腦和手機(jī)咽弦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)胁出,“玉大人型型,你說(shuō)我怎么就攤上這事』耄” “怎么了输莺?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)裸诽。 經(jīng)常有香客問(wèn)我嫂用,道長(zhǎng),這世上最難降的妖魔是什么丈冬? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任嘱函,我火速辦了婚禮,結(jié)果婚禮上埂蕊,老公的妹妹穿的比我還像新娘往弓。我一直安慰自己,他們只是感情好蓄氧,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布函似。 她就那樣靜靜地躺著,像睡著了一般喉童。 火紅的嫁衣襯著肌膚如雪撇寞。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,741評(píng)論 1 289
  • 那天堂氯,我揣著相機(jī)與錄音蔑担,去河邊找鬼。 笑死咽白,一個(gè)胖子當(dāng)著我的面吹牛啤握,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播晶框,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼排抬,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼懂从!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起蹲蒲,我...
    開(kāi)封第一講書(shū)人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤莫绣,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后悠鞍,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體对室,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年咖祭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了掩宜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡么翰,死狀恐怖牺汤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情浩嫌,我是刑警寧澤檐迟,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站码耐,受9級(jí)特大地震影響追迟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜骚腥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一敦间、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧束铭,春花似錦廓块、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至懈万,卻和暖如春拴清,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背钞速。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工贷掖, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嫡秕,地道東北人渴语。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像昆咽,于是被迫代替她去往敵國(guó)和親驾凶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子牙甫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容