RxJava系列的文章已经写了有七篇了,相信读者已经对它比较熟悉了。
介绍了那么多,那么到底RxJava在真实开发中会有哪些地方用到呢?今天和大家介绍一下它的经典使用场景。
RxJava + Retrofit
Retrofit 除了提供了传统的 Callback 形式的 API,还有 RxJava 版本的 Observable 形式 API。下面我用对比的方式来介绍 Retrofit 的 RxJava 版 API 和传统版本的区别。
以获取一个 MovieEntity 对象的接口作为例子。使用Retrofit 的传统 API,你可以用这样的方式来定义请求:
@GET("top250")
Call<MovieEntity> getTopMovie(@Query("start") int start, @Query("count") int count);//正常返回Call对象
我们来写getMovie方法的代码:
//进行网络请求
private void getMovie(){
String baseUrl = "https://api.douban.com/v2/movie/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
MovieService movieService = retrofit.create(MovieService.class);
Call<MovieEntity> call = movieService.getTopMovie(0, 10);
call.enqueue(new Callback<MovieEntity>() {
@Override
public void onResponse(Call<MovieEntity> call, Response<MovieEntity> response) {
resultTV.setText(response.body().toString());
}
@Override
public void onFailure(Call<MovieEntity> call, Throwable t) {
resultTV.setText(t.getMessage());
}
});
}
以上为没有经过封装的、原生态的Retrofit写网络请求的代码。
而使用 RxJava 形式的 API,定义同样的请求是这样的:
@GET("top250")
Observable<MovieEntity> getTopMovie(@Query("start") int start, @Query("count") int count);//RxJava返回Observable对象
Retrofit本身对Rxjava提供了支持,getMovie方法改为:
//进行网络请求
private void getMovie(){
String baseUrl = "https://api.douban.com/v2/movie/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//提供RXjava支持
.build();
MovieService movieService = retrofit.create(MovieService.class);
movieService.getTopMovie(0, 10)//返回Observable对象
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<MovieEntity>() {
@Override
public void onCompleted() {
Toast.makeText(MainActivity.this, "Get Top Movie Completed", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable e) {
resultTV.setText(e.getMessage());
}
@Override
public void onNext(MovieEntity movieEntity) {
resultTV.setText(movieEntity.toString());
}
});
}
这样基本上就完成了Retrofit和Rxjava的结合,大家可以自己进行封装;那么用上了RxJava,我们就可以用它强大的操作符来对数据进行处理和操作,各位看官可以具体去实现,我在这里不做多做赘述。
RxBinding
RxBinding 是 Jake Wharton 的一个开源库,它提供了一套在 Android 平台上的基于 RxJava 的 Binding API。所谓 Binding,就是类似设置 OnClickListener 、设置 TextWatcher 这样的注册绑定对象的 API。
举个设置点击监听的例子。使用 RxBinding ,可以把事件监听用这样的方法来设置:
Button button = ...;
RxView.clickEvents(button) // 以 Observable 形式来反馈点击事件
.subscribe(new Action1<ViewClickEvent>() {
@Override
public void call(ViewClickEvent event) {
// Click handling
}
});
看起来除了形式变了没什么区别,实质上也是这样。甚至如果你看一下它的源码,你会发现它连实现都没什么惊喜:它的内部是直接用一个包裹着的 setOnClickListener() 来实现的。然而,仅仅这一个形式的改变,却恰好就是 RxBinding 的目的:扩展性。通过 RxBinding 把点击监听转换成 Observable 之后,就有了对它进行扩展的可能。扩展的方式有很多,根据需求而定。一个例子是前面提到过的 throttleFirst() 操作符,用于去抖动,也就是消除手抖导致的快速连环点击:
RxView.clickEvents(button)
.throttleFirst(500, TimeUnit.MILLISECONDS)
.subscribe(clickAction);
如果想对 RxBinding 有更多了解,可以去它的 GitHub 项目 下面看看。
RxLifecyle
RxLifecycle 配合 Activity/Fragment 生命周期来管理订阅的。 由于 RxJava Observable 订阅后(调用 subscribe 函数),一般会在后台线程执行一些操作(比如访问网络请求数据),当后台操作返回后,调用 Observer 的 onNext 等函数,然后在 更新 UI 状态。 但是后台线程请求是需要时间的,如果用户点击刷新按钮请求新的微博信息,在刷新还没有完成的时候,用户退出了当前界面返回前面的界面,这个时候刷新的 Observable 如果不取消订阅,则会导致之前的 Activity 无法被 JVM 回收导致内存泄露。 这就是 Android 里面的生命周期管理需要注意的地方,RxLifecycle 就是用来干这事的。比如下面的示例:
myObservable
.compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY))
.subscribe();
这样Activity在destroy的时候就会自动取消这个observer。
RxBus
RxBus并不是一个库,而是一种模式。相信大多数开发者都使用过EventBus或者Otto,作为事件总线通信库,如果你的项目已经加入RxJava和EventBus,不妨用RxBus代替EventBus,以减少库的依赖。RxJava也可以轻松实现事件总线,因为它们都依据于观察者模式。
RxPermission
RxPermission是基于RxJava开发的用于帮助在Android 6.0中处理运行时权限检测的框架。在Android 6.0中,系统新增了部分权限的运行时动态获取。而不再是在以前的版本中安装的时候授予权限。
总结
简而言之Rxjava是一个很牛逼的库,如果你的项目中还没有使用RxJava的话,建议可以尝试去集成使用;对大多数人而已RxJava是一个比较难上手的库了,不亚于Dagger的上手难度;不过当你认识学习使用过了,你就会发现RxJava的魅力所在;如果看一遍没有看懂的童鞋,建议多看几次;动手写写代码,我想信本文可以给到你们一些帮助;你们真正的体会到什么是 从入门到放弃再到不离不弃 ;这就是RxJava的魅力所在。
系列文章
RxJava从入门到不离不弃(六)——Scheduler线程调度
更多精彩内容,欢迎关注我的微信公众号——Android机动车