这篇文章将介绍RxPermissions、ReactiveNetwork、RxBinding的使用
自从rxjava出现以来,Android领域出现了各种各样基于rxjava开源的库,有处理权限操作的RxPermissions、处理网络状态监听的ReactiveNetwork、处理事件绑定的RxBinding、处理蓝牙问题的RxAndroidBle 等等。
在介绍rxjava与Android相关的开源库之前,我们还需要了解rxjava另一个非常重要的概念。
Scheduler
在rxjava中,Scheduler相当于线程控制器,rxjava通过Scheduler来指定每一段代码应该运行在什么样的线程中。rxjava内置了几种Scheduler,我们先不去关心,这里我们只了解2中Scheduler:
- AndroidSchedulers.mainThread(),Android专用的调度器,它指定的操作符将在Android主线程中运行;
- Schedulers.io(),I/O操作(读写文件、读写数据库、网络信息交互等)所使用的Scheduler。行为模式和newThread()差不多,区别在于io()的内部实现是一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下io()比newThread()更有效率。不要把计算工作放在io()中,可以避免创建不必要的线程。
因此在Android中是用哪个rxjava系列库通常要引入rxandroid的依赖,当然一些第三方的rx库已经自己引入了rxandroid,具体看项目External Libraries中是否已经导入rxandroid包。
RxPermissions的使用
引入RxPermissions
compile 'com.tbruyelle.rxpermissions:rxpermissions:0.9.4@aar'
相信对于Android开发人员来说,6.0带来的权限问题并不陌生。许多动态权限需要我们在编码过程中动态获取,然后在权限回调方法中进行相应的事件处理。相信很多开发者会因为权限问题带来的编码工作而烦恼,究竟如何使用、如何封装才是最佳的实现方式。RxPermissions可以很好的帮我们处理权限问题:
实例一
RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions.request(Manifest.permission.CAMERA)
.subscribe(new Action1<Boolean>() {
@Override
public void call(Boolean aBoolean) {
if(aBoolean){
Toast.makeText(RxPermissionTestActivity.this,"您允许了相机权限",Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(RxPermissionTestActivity.this,"您拒绝了相机权限",Toast.LENGTH_SHORT).show();
}
}
});
非常简单,只需要在Activity或者Fragment初始化RxPermissions实例,然后调用其简单方法就可以实现动态权限的申请。mm再也不用担心权限问题带来的编码困扰了。简单说下,RxPermissions是通过创建透明Fragment进行其跟Activity的关联和生命周期的管理。
RxBinding使用
引入rxbinding
compile 'com.jakewharton.rxbinding:rxbinding:0.4.0'
rxbindview是用来帮助控件处理各种点击事件的开源库,并不提供控件初始化的功能。
实例二
这里的demo我们事先一个小功能,参考网上一个大神blog写的。一个listview,一个EditText,我们监听EditText中文字的输入来动态显示下面的列表,列表中数据根据输入框内容动态模糊查询:
mListView = (ListView) findViewById(R.id.listview);
final ArrayAdapter<String> mAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_expandable_list_item_1);
mListView.setAdapter(mAdapter);
RxTextView.textChanges(mEditText)
.debounce(600,TimeUnit.MILLISECONDS)
.map(new Func1<CharSequence, String>(){//获取输入框内容
@Override
public String call(CharSequence charSequence) {
return charSequence.toString();
}
})
.observeOn(Schedulers.io())//转换线程
.map(new Func1<String, List<String>>() {
@Override
public List<String> call(String str) {
List<String> dataList = new ArrayList<String>() ;
if ( ! TextUtils.isEmpty(str)){
for ( String s : getData() ) {
if (s != null) {
if (s.contains(str)) {
dataList.add(s);
}
}
}
}
return dataList ;
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<List<String>>() {
@Override
public void call(List<String> strings) {
mAdapter.clear();
mAdapter.addAll( strings );
mAdapter.notifyDataSetChanged();
}
});
可以看到,通过rxbing的RxTextView的textChanges()我们就可以实现输入框文本内容变化的监听,这里设置文本变化600ms后执行map操作符获取到文本框输入的文本,然后将事件转向I/O操作中(类似去网络请求),接下来map中的事件将在I/O线程中进行(过滤数据,只显示包含输入框输入字符串的字符串列表),之后又将事件转向Android主线程执行,也就是最后的观察者事件在主线程中执行,通知adapter列表数据的变化。其中getData()方法就是模拟一组数据
private List<String> getData(){
List<String> strs = new ArrayList<>();
strs.add("12");
strs.add("123");
strs.add("1234");
return strs;
}
实例三
下面的demo将实现这样一个功能,通过rxbinding和rxPermissions的结合,实现button点击事件过程中,确保点击button时候要求的相机运行时权限已被申请的前提下才去执行具体的点击事件
RxView.clicks(mButton)
.compose(rxPermissions.ensure(Manifest.permission.CAMERA))
.subscribe(new Action1<Boolean>() {
@Override
public void call(Boolean aBoolean) {
if(aBoolean)
Toast.makeText(RxPermissionTestActivity.this,"您点击了按钮",Toast.LENGTH_SHORT).show();
}
});
}
实例四
这个demo实现一个按钮点击事件,2s内只允许执行一次点击事件方法,可以有效避免按钮被快速重复点击导致点击事件方法被频繁的重复调用
RxView.clicks(button)
.throttleFirst(2, TimeUnit.SECONDS)
.subscribe(new Action1<Void>() {
@Override
public void call(Void aVoid) {
Toast.makeText(RxBindingTestActivity.this,"单击事件",Toast.LENGTH_SHORT).show();
}
});
ReactiveNetwork的使用
引入ReactiveNetwork:
compile 'com.github.pwittchen:reactivenetwork:0.9.1'
实例五
网络状态变化的监听也是项目中常用的一个功能,通常都是通过监听系统广播来实现网络状态变化的监听事件,ReactiveNetwork可以很好的帮助我们实现网络事件的监听
ReactiveNetwork.observeNetworkConnectivity(this)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Connectivity>() {
@Override
public void call(Connectivity connectivity) {
String connectStr = connectivity.toString();
mTextView.setText(connectStr);
}
});
被观察者事件在I/O线程中实现网络事件监听,观察者事件在Android主线程中执行。当监听到网络状态变化的时候,通知观察者在主线程进行监听事件操作。这里返回的Connectivity对象包含了网络所有的状态信息。
实例六
还有更简单的实现网络是否连接的监听
ReactiveNetwork.observeInternetConnectivity()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Boolean>() {
@Override
public void call(Boolean aBoolean) {
if(aBoolean)
Toast.makeText(ReactiveNetworkText.this,"网络可用",Toast.LENGTH_SHORT).show();
else
Toast.makeText(ReactiveNetworkText.this,"对不起,网络不可用",Toast.LENGTH_SHORT).show();
}
});
}
至此,rxjava有关的Android框架介绍完了。其实除了上面这几个,还有很多rx系列的Android开源库,有兴趣的同学可以自己去github上面了解。通过这几篇文章的介绍,相信你对rxjava有了较深入的理解,至于具体的使用以及功能的开发还需要我们具体在项目实战中去积累。
欢迎大家留言讨论,之后我将继续对rxjava和retrofit2的使用继续进行总结。