天天看點

RxJava系列一(簡介)

RxJava系列一(簡介)

前言

提升開發效率,降低維護成本一直是開發團隊永恒不變的宗旨。近一年來國内的技術圈子中越來越多的開始提及Rx,經過一段時間的學習和探索之後我也深深的感受到了RxJava的魅力。它能幫助我們簡化代碼邏輯,提升代碼可讀性。這對于開發效率的提升、後期維護成本的降低幫助都是巨大的。個人預測RxJava一定是2016年的一個大趨勢,是以也有打算将它引入到公司現有的項目中來,寫這一系列的文章主要也是為了團隊内部做技術分享。

由于我本人是個Android程式猿,是以這一系列文章中的場景都是基于Android平台的。如果你是個Java Web工程師或者是其它方向的那也沒關系,我會盡量用通俗的語言将問題描述清楚。

響應式程式設計

在介紹RxJava前,我們先聊聊響應式程式設計。那麼什麼是響應式程式設計呢?響應式程式設計是一種基于異步資料流概念的程式設計模式。資料流就像一條河:它可以被觀測,被過濾,被操作,或者為新的消費者與另外一條流合并為一條新的流。

響應式程式設計的一個關鍵概念是事件。事件可以被等待,可以觸發過程,也可以觸發其它事件。事件是唯一的以合适的方式将我們的現實世界映射到我們的軟體中:如果屋裡太熱了我們就打開一扇窗戶。同樣的,當我們的天氣app從服務端擷取到新的天氣資料後,我們需要更新app上展示天氣資訊的UI;汽車上的車道偏移系統探測到車輛偏移了正常路線就會提醒駕駛者糾正,就是是響應事件。

今天,響應式程式設計最通用的一個場景是UI:我們的移動App必須做出對網絡調用、使用者觸摸輸入和系統彈框的響應。在這個世界上,軟體之是以是事件驅動并響應的是因為現實生活也是如此。

本章節中部分概念摘自《RxJava Essentials》一書

RxJava的來曆

Rx是微軟.Net的一個響應式擴充,Rx借助可觀測的序列提供一種簡單的方式來建立異步的,基于事件驅動的程式。2012年Netflix為了應對不斷增長的業務需求開始将.NET Rx遷移到JVM上面。并于13年二月份正式向外展示了RxJava。

從語義的角度來看,RxJava就是.NET Rx。從文法的角度來看,Netflix考慮到了對應每個Rx方法,保留了Java代碼規範和基本的模式。

RxJava系列一(簡介)

什麼是RxJava

那麼到底什麼是RxJava呢?我對它的定義是:RxJava本質上是一個異步操作庫,是一個能讓你用極其簡潔的邏輯去處理繁瑣複雜任務的異步事件庫。

RxJava好在哪

Android平台上為已經開發者提供了AsyncTask,Handler等用來做異步操作的類庫,那我們為什麼還要選擇RxJava呢?答案是簡潔!RxJava可以用非常簡潔的代碼邏輯來解決複雜問題;而且即使業務邏輯的越來越複雜,它依然能夠保持簡潔!再配合上Lambda用簡單的幾行代碼分分鐘就解決你負責的業務問題。簡直逼格爆表,拿它裝逼那是極好的!

多說無益,上代碼!

假設我們安居客使用者App上有個需求,需要從服務端拉取上海浦東新區塘橋闆塊的所有小區Community[] communities,每個小區下包含多套房源Listhouses;我們需要把塘橋闆塊的所有總價大于500W的房源都展示在App的房源清單頁。用于從服務端拉取communities需要發起網絡請求,比較耗時,是以需要在背景運作。而這些房源資訊需要展示到App的頁面上,是以需要在UI線程上執行。(此例子思路來源于扔物線的給Android開發者的RxJava詳解一文)

new Thread() {
        @Override
        public void run() {
            super.run();
            //從服務端擷取小區清單
            List<Community> communities = getCommunitiesFromServer();
            for (Community community : communities) {
                List<House> houses = community.houses;
                for (House house : houses) {
                    if (house.price >= 5000000) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                //将房子的資訊添加到螢幕上
                                addHouseInformationToScreen(house);
                            }
                        });
                    }
                }
            }
        }
    }.start();           

複制

使用RxJava的寫法是這樣的:

Observable.from(getCommunitiesFromServer())
            .flatMap(new Func1<Community, Observable<House>>() {
                @Override
                public Observable<House> call(Community community) {
                    return Observable.from(community.houses);
                }
            }).filter(new Func1<House, Boolean>() {
                @Override
                public Boolean call(House house) {
                    return house.price>=5000000;
                }
            }).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Action1<House>() {
                @Override
                public void call(House house) {
                    //将房子的資訊添加到螢幕上
                    addHouseInformationToScreen(house);
                }
            });           

複制

從上面這段代碼我們可以看到:雖然代碼量看起來變複雜了,但是RxJava的實作是一條鍊式調用,沒有任何的嵌套;整個實作邏輯看起來異常簡潔清晰,這對我們的程式設計實作和後期維護是有巨大幫助的。特别是對于那些回調嵌套的場景。配合Lambda表達式還可以簡化成這樣:

Observable.from(getCommunitiesFromServer())
        .flatMap(community -> Observable.from(community.houses))
        .filter(house -> house.price>=5000000).subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(this::addHouseInformationToScreen);           

複制

簡潔!有美感!這才是一個有情懷的程式員應該寫出來的代碼。

看完這篇文章大家應該能夠了解RxJava為什麼會越來越火了。它能極大的提高我們的開發效率和代碼的可讀性!當然了RxJava的學習曲線也是比較陡的,在後面的文章我會對主要的知識點做詳細的介紹,敬請關注!

如果你喜歡我的文章,就關注下我的知乎專欄或者在 GitHub 上添個 Star 吧!
  • 知乎專欄:https://zhuanlan.zhihu.com/baron
  • GitHub:https://github.com/BaronZ88