前提

需要知道什么是 RxJava
这里推荐下 扔物线写的 给 Android 开发者的 RxJava 详解
再感谢 RxJava 与 Retrofit 结合的最佳实践 这篇满满的干货。

实战

准备

项目中用到的依赖:

compile 'io.reactivex:rxjava:1.1.0'compile 'io.reactivex:rxandroid:1.1.0'compile 'com.google.code.gson:gson:2.4'compile 'com.squareup.retrofit2:retrofit:2.0.2'compile 'com.squareup.retrofit2:converter-gson:2.0.2'compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'compile 'com.squareup.okhttp3:okhttp:3.0.1'compile 'com.squareup.okhttp3:logging-interceptor:3.0.1'compile 'com.squareup.okio:okio:1.6.0'

因为要用到网络,所以千万别忘记了这个权限。

<uses-permission android:name="android.permission.INTERNET"/>

组件 Rx 封装的工具

使用compose操作符

compose()里接收一个Transformer对象,Transformer继承自Func1<Observable<T>, Observable<R>>,可以通过它将一种类型的Observable转换成另一种类型的Observable。

RxSchedulerHelper

封装 Rx 线程相关操作

public static <T> Observable.Transformer<T, T> rxSchedulerHelper() {    return tObservable -> tObservable.subscribeOn(Schedulers.io())        .unsubscribeOn(AndroidSchedulers.mainThread())        .observeOn(AndroidSchedulers.mainThread());}

handleResult

封装 API 请求后统一处理

public static <T> Observable.Transformer<Result<T>, T> handleResult() {    return resultObservable -> resultObservable.flatMap(tResult -> {        if (tResult.code == 1) {            return createData(tResult.data);        } else {            return Observable.error(new ApiException(tResult.code));        }    });}

RetrofitSingleton

自己封装了下 Retrofit。可以学习下小艾的方式。
自己将请求是写在该类,使用者只需要关心如何处理拿到的数据和相应的 UI 操作。

public Observable<Weather> fetchWeather(String city) {    return apiService.mWeatherAPI(city, C.KEY)        .filter(weatherAPI -> weatherAPI.mHeWeatherDataService30s.get(0).status.equals("ok"))        .map(weatherAPI -> weatherAPI.mHeWeatherDataService30s.get(0))        .compose(RxUtils.rxSchedulerHelper());}public Observable<VersionAPI> fetchVersion() {    return apiService.mVersionAPI(C.API_TOKEN).compose(RxUtils.rxSchedulerHelper());}

使用

将网络拉取和读取缓存用 Rx 结合。
这里就要使用 concat 操作符,官方解释.
首先看看获取网络是如何写的:

private Observable<Weather> fetchDataByNetWork() {    String cityName = Util.replaceCity(mSetting.getCityName());    return RetrofitSingleton.getInstance()        .fetchWeather(cityName)        .onErrorReturn(throwable -> {            PLog.e(throwable.getMessage());            return null;        });}

这里的 onErrorReturn 待会儿说。
再来看看读取缓存的代码:

private Observable<Weather> fetchDataByCache() {    return Observable.defer(() -> { Weather weather = (Weather) aCache.getAsObject(C.WEATHER_CACHE); return Observable.just(weather); }); }

然后我们将他们连接起来:

private void load() {    Observable.concat(fetchDataByNetWork(), fetchDataByCache())        .first(weather -> weather != null)        .doOnError(throwable -> {            mErroImageView.setVisibility(View.VISIBLE);            mRecyclerView.setVisibility(View.GONE);        })        .doOnNext(weather -> {            mErroImageView.setVisibility(View.GONE);            mRecyclerView.setVisibility(View.VISIBLE);        })        .doOnTerminate(() -> {            mRefreshLayout.setRefreshing(false);            mProgressBar.setVisibility(View.GONE);        })        .subscribe(observer);}

concat + first 连接和过滤的操作实现了,网络+缓存的逻辑。
刚刚为什么说要在网络代码那里使用 onErrorReturn 呢?
如果不写,网络发生异常的话,整个流就会直接走 onError ,不会执行到读取缓存的流。

结语

Rx 的各种操作符的不同组合就可以实现不同的效果。本身 Rx 封装已经足够好了,我们加工的时候一定要想到是否破坏了他本身的优雅。
因为 Rx 是一种数据流链式结构的编程思想,我们在封装时应该不能打断其链式结构。
欢迎互相讨论和探讨 :)

转自:http://imxie.cc/2016/05/24/RxJava-Retrofit-的实际应用场景/

更多相关文章

  1. Qt For Android(安卓)数据库操作
  2. 【开源项目12】Retrofit – Java(Android) 的REST 接口封装类库
  3. android java file 清理垃圾获取文件大小 删除文件等操作
  4. Android(安卓)本地文件、文件夹操作
  5. android 4.3 操作源码实现系统截屏(暂无移植性)
  6. Unity 游戏框架搭建 (十二) 简易AssetBundle打包工具(二)
  7. Android(安卓)ADB命令大全(通过ADB命令查看wifi密码、MAC地址、
  8. 【原】Android多任务下载,使用Notification更新进度条
  9. Flutter的一些冷门操作

随机推荐

  1. Android相关属性的介绍:android:exported
  2. [开源]在iOS上实现Android风格的控件Toas
  3. #引用资源的两种方式 在java中R.string.a
  4. Android小项目:计算器
  5. Android(安卓)USB串口开发
  6. 关于实现判断用户是在PC端和还是移动端访
  7. android怎么引入第三方包,引入其他包
  8. Android中如何使用rotate实现图片不停旋
  9. Android获取父类容器中控件的方法
  10. Android内存泄漏(使用单例模式造成的内存