关于

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 是一种数据流链式结构的编程思想,我们在封装时应该不能打断其链式结构。

RxJava + Retrofit 的实际应用场景的更多相关文章

  1. 开发 Material Design+RxJava+Retrofit+MVP App 参考资料

    前言     在开发一个基于 Material Design+RxJava+Retrofit+MVP 框架的 App 过程中学习的资料整理 —— 由G军仔分享 这里记录了我开发 大象 项目时,所学习的 ...

  2. 手把手带你走进MVP +Dagger2 + DataBinding+ Rxjava+Retrofit 的世界

    0.0 Android开发现在的变化用一个词来形容就是 :翻天覆地 越来越多的项目使用了MVP + Rxjava+Retrofit +Dagger2 + DataBinding等等东西.. 但是这些东 ...

  3. Rxjava + retrofit + dagger2 + mvp搭建Android框架

    最近出去面试,总会被问到我们项目现在采用的什么开发框架,不过据我的经验网络框架(volley)+图片缓存(uIl)+数据库(orm)+mvp,不过现在这套框架比较好了,现在采用什么呢?Rxjava + ...

  4. RxJava+Retrofit+OkHttp,一步一步封装网络框架;

    使用RxJava+Retrofit+OkHttp,首先在build.gradle添加: compile 'com.squareup.okhttp3:okhttp:3.8.1' compile 'com ...

  5. RxJava + Retrofit完成网络请求

    1.前言 本文基于RxJava.Retrofit的使用,若是对RxJava或Retrofit还不了解的简友可以先了解RxJava.Retrofit的用法再来看这篇文章. 在这片文章之前分别单独介绍过R ...

  6. Android RxJava+Retrofit完美封装

    作者简介 本篇来自 小河马 的投稿,分享了自己是如何进行 RxJava+Retrofit 的封装.本文的技术点自然没话说,另外对于这种模块化的思路,希望能帮助到大家.最后提前祝大家周末愉快以及圣诞快乐 ...

  7. Rxjava+retrofit+mvp整合

    转载请标明出处: http://blog.csdn.net/forezp/article/details/52621898 本文出自方志朋的博客 最近在看Rxjava,写了一个简单的 demo整合了R ...

  8. RxJava+Retrofit实现网络请求

    RxJava+Retrofit实现网络请求: 首先要添加依赖 compile 'io.reactivex:rxjava:x.y.z' compile 'io.reactivex:rxandroid:1 ...

  9. android打飞机游戏、MVP句子迷App、悬浮窗、RxJava+Retrofit、加载动画、定制计划App等源码

    Android精选源码 微信打飞机 android进度设置加载效果源码 Android新手引导库EasyGuide MVP-好看又好用的句子迷客户端 XFloatView 一个简易的悬浮窗实现方案 a ...

随机推荐

  1. HDU 3829 - Cat VS Dog (二分图最大独立集)

    题意:动物园有n只猫和m条狗,现在有p个小孩,他们有的喜欢猫,有的喜欢狗,其中喜欢猫的一定不喜欢狗,喜欢狗的一定不喜欢猫.现在管理员要从动物园中移除一些动物,如果一个小孩喜欢的动物留了下来而不喜欢的动 ...

  2. java中判断字符串是否为数字的三种方法

    以下内容引自  http://www.blogjava.net/Javaphua/archive/2007/06/05/122131.html 1用JAVA自带的函数   public static ...

  3. 外部表与partition

    在建立普通表的时候,如果数据是有分区的,在ADD DATA的时候需要指明分区,比方下面的例子: user表,包含 id bigint,name string,然后按照时间(date)来进行分区,路径存 ...

  4. 关于Android Studio里的Gradle,你所需要知道的都在这里了

    Gradle介绍 Gradle是一个先进的build toolkit,可以方便的管理依赖包和定义自己的build逻辑.到底有多先进,Android Studio官方集成Gradle,Google还专门 ...

  5. iOS传值方式:属性,代理,block,单例,通知

    正向传值均可,反向传值除属性传值不可,其余均可.下面简单介绍: (一)属性传值 第二个界面中的lable显示第一个界面textField中的文本 首先我们建立一个RootViewControllers ...

  6. 修复Dll文件

    for %1 in (%windir%\system32\*.dll) do regsvr32.exe /s %1

  7. Makefile学习(1) arm-linux-ld arm-linux-objcopy arm-linux-objdump

    记录自己所学的点点滴滴O(∩_∩)O哈哈~ makefile: link.bin: start.o main.o arm-linux-ld -Tlink.lds -o link.elf $^ arm- ...

  8. js获取非行内样式

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. java zip文件的解压缩(支持中文文件名)

    用的apache的ant包,下载导入即可.由于过程比较简单,直接上代码. 代码可直接复制使用. 如果想在android上使用,记得要在AndroidManifest.xml里添加权限: <use ...

  10. 2015GitWebRTC编译实录9

    2015.07.20 neteq 编译通过注意不要引用tools目录里的内容 [1347/1600 ] CXX obj /webrtc/modules/audio_coding/neteq/neteq ...