RxJava系列7(最佳實踐)

圖片來自網(wǎng)絡(luò)

轉(zhuǎn)載請注明出處:http://www.itdecent.cn/p/b0d8d3a5d3fc

前言

有點標(biāo)題黨了,其實談不上什么最佳實踐。前段時間公司實行996,所以也沒什么時間和精力來更新博客(好吧我承認(rèn)是我懶)。因此這篇文章只是簡單的通過兩個例子介紹了RxJava在生產(chǎn)環(huán)境中的使用。不過本篇中的每個例子我都配上了完整的代碼。

按照計劃這一期是要介紹RxJava框架結(jié)構(gòu)和設(shè)計思想的,但是考慮到Netflix將在十月底發(fā)布RxJava2.0正式版;因此決定將RxJava框架結(jié)構(gòu)和設(shè)計思想分析放到2.0正式版發(fā)布后再做。后續(xù)我也會有一系列的文章來介紹RxJava1.x和2.x的區(qū)別。

示例一、獲取手機上已安裝的App

第一個例子我們需要在Android設(shè)備上展示已安裝的第三方app列表,關(guān)于環(huán)境搭建、依賴配置、RecyclerView的使用等這些基礎(chǔ)內(nèi)容我就不做陳述了。需要了解的同學(xué)可以去GitHub上把項目clone下來看看。這里我主要講講如何通過RxJava實現(xiàn)核心功能。

首選我們需要調(diào)用系統(tǒng)api來獲取所有已安裝的app,所以在OnSubscribecall方法中調(diào)用getApplicationInfoList()。但是getApplicationInfoList()獲取的數(shù)據(jù)并不能完全滿足我們的業(yè)務(wù)需求:

  1. 由于我們只需要展示手機上已安裝的第三方App,因此需要通過filter操作符來過濾掉系統(tǒng)app;
  2. ApplicationInfo并不是我們所需要的類型,因此需要通過map操作符將其轉(zhuǎn)換為AppInfo;
  3. 由于獲取ApplicationInfo、過濾數(shù)據(jù)、轉(zhuǎn)換數(shù)據(jù)相對比較耗時,因此需要通過subscribeOn操作符將這一系列操作放到子線程中來處理;
  4. 而要將信息展示在頁面上涉及到UI操作,因此需要通過observeOn操作符將onNext、onCompletedonError調(diào)度到主線程,接著我們在這些方法中更新UI。

下面是核心代碼:

final PackageManager pm = MainActivity.this.getPackageManager();
Observable.create(new Observable.OnSubscribe<ApplicationInfo>() {
        @Override
        public void call(Subscriber<? super ApplicationInfo> subscriber) {
            List<ApplicationInfo> infoList = getApplicationInfoList(pm);
            for (ApplicationInfo info : infoList) {
                subscriber.onNext(info);
            }
            subscriber.onCompleted();
        }
    }).filter(new Func1<ApplicationInfo, Boolean>() {
        @Override
        public Boolean call(ApplicationInfo applicationInfo) {
            return (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) <= 0;
        }
    }).map(new Func1<ApplicationInfo, AppInfo>() {

        @Override
        public AppInfo call(ApplicationInfo applicationInfo) {
            AppInfo info = new AppInfo();
            info.setAppIcon(applicationInfo.loadIcon(pm));
            info.setAppName(applicationInfo.loadLabel(pm).toString());
            return info;
        }
    }).subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Subscriber<AppInfo>() {
        @Override
        public void onCompleted() {
            mAppListAdapter.notifyDataSetChanged();
            mPullDownSRL.setRefreshing(false);
        }

        @Override
        public void onError(Throwable e) {
            mPullDownSRL.setRefreshing(false);
        }

        @Override
        public void onNext(AppInfo appInfo) {
            mAppInfoList.add(appInfo);
        }
    });

程序執(zhí)行效果圖:


效果圖

完整的代碼我放到了GitHub上,有興趣大家可以去clone下來自己運行看看。

源碼地址:https://github.com/BaronZ88/HelloRxAndroid

示例二、RxJava+Retrofit2實現(xiàn)獲取天氣數(shù)據(jù)

RxJava + Retrofit2幾乎是Android應(yīng)用開發(fā)的標(biāo)配了,這個例子中我們就來聊聊這二者是如何配合起來幫助我們快速開發(fā)的。

Retrofit2中一個標(biāo)準(zhǔn)的接口定義是這樣的:

@GET("weather")
Observable<Weather> getWeather(@Query("cityId") String cityId);

現(xiàn)在有了RxJava,一個基本的網(wǎng)絡(luò)請求我們便可以這樣實現(xiàn):

ApiClient.weatherService.getWeather(cityId)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Weather>() {
                    @Override
                    public void call(Weather weather) {
                        weatherView.displayWeatherInformation(weather);
                    }
                });

但有時候可能一開始我們并不知道cityId,我們只知道cityName。所以就需要我們先訪問服務(wù)器,拿到對應(yīng)城市名的cityId,然后通過這個cityId再去獲取天氣數(shù)據(jù)。

同樣的,我們需要定義一個獲取cityId的接口:

@GET("city")
Observable<String> getCityIdByName(@Query("cityName") String cityName);

緊接著我們便可以使用無所不能的RxJava來實現(xiàn)需求了。

ApiClient.weatherService.getCityIdByName("上海")
             .flatMap(new Func1<String, Observable<Weather>>() {
                 @Override
                 public Observable<Weather> call(String cityId) {
                     return ApiClient.weatherService.getWeather(cityId);
                 }
             }).subscribeOn(Schedulers.io())
             .observeOn(AndroidSchedulers.mainThread())
             .subscribe(new Action1<Weather>() {
                 @Override
                 public void call(Weather weather) {
                     weatherView.displayWeatherInformation(weather);
                 }
             });

哇哦!~ so easy!??!媽媽再也不用擔(dān)心....

源碼地址:https://github.com/BaronZ88/WeatherStyle

WeatherStyle這個項目還在開發(fā)中,這個項目不只包含了RxJava和Retrofit的使用,同時還包含MVP、ORMLite、RetroLambda、ButterKnife等等開源庫的使用

RxJava1.X的系列文章就到此結(jié)束了,由于本人對RxJava的理解有限,這一系列文章中如有錯誤還請大家指正。在使用RxJava過程中有任何疑問也歡迎大家和我交流。共同學(xué)習(xí)!共同進(jìn)步!

好啦,我們RxJava2見!~


如果大家喜歡這一系列的文章,歡迎關(guān)注我的知乎專欄、GitHub、簡書博客。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容