RxJava極簡學習(四個簡單例子)

RxJava

提到Rxjava最多人都是用來處理舍沙,線程調(diào)度嘱腥,回調(diào)地獄州弟,加上Retrofit又支持Rxjava暇咆,所以大部分開發(fā)者都只會在請求網(wǎng)絡(luò)和需要切換線程的時候用到Rxjava,其實它有一個最重要的特性塔插,它可以讓數(shù)據(jù)的流向更加直觀梗摇,代碼更清晰。

舉個栗子

比如說一個龐大的項目想许,一個事件傳遞的整個過程可能要經(jīng)歷很多方法伶授,方法套方法断序,每個方法的位置七零八落,一個個方法跳進去看,跳過去跳過來很容易把腦袋弄暈糜烹,不夠直觀违诗。但是Rxjava可以把所有邏輯用鏈式加閉包的方式呈現(xiàn),做了哪些操作疮蹦,誰在前誰在后非常直觀诸迟,邏輯清晰,維護就會非常輕松愕乎。就算不是你寫的你也可以很快的了解阵苇,你可以把它看作一條河流,整個過程就是對里面的水流做進行加工感论。懂了這個特性我們才知道在復雜的邏輯中運用Rxjava是多么的重要绅项。

Gradle添加依賴

要在Android中使用RxJava2, 先添加Gradle配置。

compile "io.reactivex.rxjava2:rxjava:2.0.7"
compile "io.reactivex.rxjava2:rxandroid:2.0.1"

一個簡單實例(分別創(chuàng)建被觀察者比肄,觀察者和兩種對象進行關(guān)聯(lián))


  //創(chuàng)建被觀察者
 Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                //調(diào)用觀察者的回調(diào)
                emitter.onNext("我是");
                emitter.onNext("RxJava");
                emitter.onNext("簡單示例");
                emitter.onError(new Throwable("出錯了"));
                emitter.onComplete();
            }
        });

        //創(chuàng)建觀察者
        Observer<String> observer = new Observer<String>() {

            @Override
            public void onError(Throwable e) {
                Log.e(TAG,e.getMessage());
            }

            @Override
            public void onComplete() {
                Log.e(TAG,"onCompleted");
            }

            //onSubscribe()方法是最先調(diào)用的
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG,"subscribe");
            }

            @Override
            public void onNext(String s) {
                Log.d(TAG,s);
            }
        };

        //注冊快耿,將觀察者和被觀察者關(guān)聯(lián),將會觸發(fā)OnSubscribe.call方法
        observable.subscribe(observer);

運行結(jié)果:

Observable是被觀察者芳绩,創(chuàng)建后傳入一個OnSubscribe對象掀亥,當Observable(觀察者)調(diào)用subscribe進行注冊觀察者時,OnSubscribe的call方法會觸發(fā)妥色。
ObservableEmitter: Emitter 是發(fā)射器的意思搪花,它可以發(fā)出三種類型的事件,與之對應的垛膝。
Observer有三個回調(diào)方法:

  • onNext:接受到一個事件
  • onCompleted:接受完事件后調(diào)用鳍侣,只會調(diào)用一次
  • onError :發(fā)生錯誤時調(diào)用,并停止接受事件吼拥,調(diào)用一次

注:onCompleted和onError不會同時調(diào)用倚聚,只會調(diào)用其中之一

另一個簡單實例(訪問網(wǎng)絡(luò)時,通過RxJava來進行快捷的主線程和子線程切換)


protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final TextView tv_return = (TextView) findViewById(R.id.tv_return);
        //創(chuàng)建被觀察者
        Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                Log.d(TAG, "Observer thread is :" + Thread.currentThread().getName());
                emitter.onNext(getResponse());
            }
        });

        //創(chuàng)建觀察者
        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String mResponse) throws Exception {
                Log.d(TAG, "Observer thread is :" + Thread.currentThread().getName());
                tv_return.setText(mResponse);
            }
        };
       //subscribeOn() 指定的是發(fā)送事件的線程, observeOn() 指定的是接收事件的線程.
        observable.subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(consumer);

    }
    //使用okhttp訪問網(wǎng)上提供的接口凿可,由于是同步get請求惑折,需要在子線程進行
    private String getResponse() {
        String url = "http://v.juhe.cn/weather/index?cityname=%E6%9D%AD%E5%B7%9E&dtype=&format=&key=7970495dbf33839562c9d496156e13cc";
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .build();
        Response response;

        try {
            response = client.newCall(request).execute();
            return response.body().string();
        } catch (IOException e) {
            return "error";
        }
    }

在RxJava中, 已經(jīng)內(nèi)置了很多線程選項供我們選擇, 例如有

  • Schedulers.io() 代表io操作的線程, 通常用于網(wǎng)絡(luò),讀寫文件等io密集型的操作
  • Schedulers.computation() 代表CPU計算密集型的操作, 例如需要大量計算的操作
  • Schedulers.newThread() 代表一個常規(guī)的新線程
  • AndroidSchedulers.mainThread() 代表Android的主線程
    這些內(nèi)置的Scheduler已經(jīng)足夠滿足我們開發(fā)的需求, 因此我們應該使用內(nèi)置的這些選項枯跑,在RxJava內(nèi)部使用的是線程池來維護這些線程惨驶,所有效率也比較高。

第三個簡單實例(類型變換操作)


RxJava提供了類型變換操作敛助,像上面的發(fā)送網(wǎng)絡(luò)請求事件粗卜,得到網(wǎng)絡(luò)請求數(shù)據(jù),傳遞和接收的都是字符串纳击。
而RxJava中的map操作符可以對事件進行處理续扔,比如發(fā)送網(wǎng)絡(luò)請求事件攻臀,通過map處理后,可以接收到網(wǎng)絡(luò)請求的字符串的字節(jié)數(shù)纱昧,如下所示刨啸。

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final TextView tv_return = (TextView) findViewById(R.id.tv_return);
        //創(chuàng)建被觀察者
        Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                Log.d(TAG, "Observer thread is :" + Thread.currentThread().getName());
                emitter.onNext(getResponse());
            }
        //通過map操作符對數(shù)據(jù)進行中間處理
        }).map(new Function<String, Integer>() {
            @Override
            public Integer apply(@NonNull String response) throws Exception {
                return response.length();
            }
        });
        //創(chuàng)建觀察者
        Consumer<Integer> consumer = new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {
                Log.d(TAG, "Observer thread is :" + Thread.currentThread().getName());
                tv_return.setText("字數(shù):"+integer);
            }
        };
        //綁定,指定線程
        observable.subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(consumer);

    }

第四個簡單實例(鏈式操作)


而RxJava一個引以為豪的地方就是它的鏈式操作了识脆,可以把被觀察者和觀察者串起來设联。

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final TextView tv_return = (TextView) findViewById(R.id.tv_return);
        
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                Log.d(TAG, "Observer thread is :" + Thread.currentThread().getName());
                emitter.onNext(getResponse());
            }
        }).map(new Function<String, Integer>() {
            @Override
            public Integer apply(@NonNull String response) throws Exception {
                return response.length();
            }
        }).subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Integer>() {
            @Override
            public void accept(@NonNull Integer integer) throws Exception {
                Log.d(TAG, "Observer thread is :" + Thread.currentThread().getName());
                tv_return.setText("字數(shù):" + integer);
            }
        });
    }

這里是項目地址 其實也沒啥東西

喜歡的同學可以點個贊

參考

https://xiaobailong24.me/2017/03/18/Android-RxJava2.x/
http://www.reibang.com/p/6fd8640046f1

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市灼捂,隨后出現(xiàn)的幾起案子离例,更是在濱河造成了極大的恐慌,老刑警劉巖纵东,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粘招,死亡現(xiàn)場離奇詭異,居然都是意外死亡偎球,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進店門辑甜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來衰絮,“玉大人,你說我怎么就攤上這事磷醋∶担” “怎么了?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵邓线,是天一觀的道長淌友。 經(jīng)常有香客問我,道長骇陈,這世上最難降的妖魔是什么震庭? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮你雌,結(jié)果婚禮上器联,老公的妹妹穿的比我還像新娘。我一直安慰自己婿崭,他們只是感情好拨拓,可當我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著氓栈,像睡著了一般渣磷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上授瘦,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天醋界,我揣著相機與錄音竟宋,去河邊找鬼。 笑死物独,一個胖子當著我的面吹牛袜硫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播挡篓,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼婉陷,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了官研?” 一聲冷哼從身側(cè)響起秽澳,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎戏羽,沒想到半個月后担神,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡始花,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年妄讯,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酷宵。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡亥贸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出浇垦,到底是詐尸還是另有隱情炕置,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布男韧,位于F島的核電站朴摊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏此虑。R本人自食惡果不足惜甚纲,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望寡壮。 院中可真熱鬧贩疙,春花似錦、人聲如沸况既。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽棒仍。三九已至悲靴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間莫其,已是汗流浹背癞尚。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工耸三, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人浇揩。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓仪壮,卻偏偏與公主長得像,于是被迫代替她去往敵國和親胳徽。 傳聞我的和親對象是個殘疾皇子积锅,可洞房花燭夜當晚...
    茶點故事閱讀 43,440評論 2 348

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

  • 我從去年開始使用 RxJava ,到現(xiàn)在一年多了养盗。今年加入了 Flipboard 后缚陷,看到 Flipboard 的...
    Jason_andy閱讀 5,460評論 7 62
  • 最近項目里面有用到Rxjava框架箫爷,感覺很強大的巨作,所以在網(wǎng)上搜了很多相關(guān)文章聂儒,發(fā)現(xiàn)一片文章很不錯虎锚,今天把這篇文...
    Scus閱讀 6,866評論 2 50
  • 前言我從去年開始使用 RxJava ,到現(xiàn)在一年多了衩婚。今年加入了 Flipboard 后翁都,看到 Flipboard...
    占導zqq閱讀 9,159評論 6 151
  • 龜二田七桑: 空氣有點涼,請不要感冒谅猾。 我猜你還在旅途中。很遺憾我無從得知你的郵編和地址鳍悠,我唯一能做的就是税娜,封好信...
    龜二田七不吃魚閱讀 181評論 0 0
  • “怎么又是你?” 聽到聲響藏研,少年猛地轉(zhuǎn)身敬矩,手上一把精致的手槍,差點走火蠢挡。 “我…我就是想看看你是怎么獵殺妖怪的弧岳。”...
    林望笙閱讀 424評論 2 3