关于RxJava原理分析,请参考仍物线写的文章—-给 Android 开发者的 RxJava 详解。本文不对原理作过多的分析,从最快上手的角度,让开发者使用起来,当我们有实践经验后回过头来看原理分析会更清晰。
本系列共有三篇文章,分别关于Rxjava的基础使用(最快,最实用),Retrofit使用(Github上star达22k+,安卓领域排名第一),最后是RxCache缓存(大部分app都支持离线查看功能)。
安卓开发进阶之RxJava在实际项目中使用–第二篇
本文是第一篇,从防止重复点击,监听内容变化,延迟操作,周期性操作,RxJava的生命周期管理,监听网络状态和权限管理七个方面介绍,这些都是我在实际项目使用到的,不是理论上的介绍。
先来看完整的运行效果
一、防止重复点击
首先添加引用
compile 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
添加代码
RxView.clicks(tv1).throttleFirst(2, TimeUnit.SECONDS)
.subscribe(new Consumer
二、监听内容变化
不需要重写EditText控件的textWacher,然后写一大堆代码了,看看下面是如何优雅的实现的。
监听单个输入框内容
RxTextView.textChanges(et1).skip(1).subscribe(new Consumer() {
@Override
public void accept(CharSequence charSequence) throws Exception {
if (TextUtils.isEmpty(charSequence.toString())) enableButton(btn1,false,0.2f);
else enableButton(btn1,true,1f);
}
});
监听多个输入框内容
Observable ob1= RxTextView.textChanges(et2).skip(1);
Observable ob2= RxTextView.textChanges(et3).skip(1);
Observable.combineLatest(ob1, ob2, new BiFunction() {
@Override
public Boolean apply(CharSequence charSequence, CharSequence charSequence2) throws Exception {
return !TextUtils.isEmpty(charSequence) && !TextUtils.isEmpty(charSequence2);//返回值可以自定义,比如至少6位
}
}).subscribe(new Consumer() {
@Override
public void accept(Boolean aBoolean) throws Exception {//aBoolean值来源于上面apply方法的返回值
if (aBoolean) enableButton(btn2,true,1f);
else enableButton(btn2,false,0.2f);
}
});
Observable.timer(3,TimeUnit.SECONDS).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer() {
@Override
public void accept(Long aLong) throws Exception { Toast.makeText(MainActivity.this,"RxJava延迟3秒操作",Toast.LENGTH_LONG).show();
}
});
四、周期性操作
周期性操作再也不用自带的Timer,不用new Timer(), new TimeTask(),这样写的零零散散,使用RxJava,让一切优雅起来。。。
Observable.interval(3,TimeUnit.SECONDS).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer() {
@Override
public void accept(Long aLong) throws Exception {
Toast.makeText(MainActivity.this,"RxJava间隔3秒周期性操作,当前时间:"+System.currentTimeMillis(),Toast.LENGTH_LONG).show();
}
});
如果上面代码中没有设置运行所在的线程subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
则会报错
io.reactivex.exceptions.OnErrorNotImplementedException: Can’t create handler inside thread that has not called Looper.prepare()
从上面的运行效果可以看到退出app后该定时操作没有被取消,所以就有了下面对RxJava的生命周期管理工–RxLifeCycle。
五、LifeCycle生命周期管理(针对上面的周期性操作
RxLifeCycle地址
先添加Maven库
maven { url "https://www.jitpack.io" }
然后添加引用
compile 'com.github.nekocode.rxlifecycle:rxlifecycle:1.1'
@Override
public void accept(Long aLong) throws Exception {
Toast.makeText(MainActivity.this,"RxJava间隔3秒周期性操作,RxLifeCycle进行生命周期管理",Toast.LENGTH_LONG).show();
}
});
第四、五两种周期性操作的区别在于Activity销毁后此操作是否能被取消,很明显,后者可以,这也是LifeCycle存在的意义。
六、监听网络状态
reactivenetwork地址
compile 'com.github.pwittchen:reactivenetwork-rx2:0.9.1'
ReactiveNetwork.observeNetworkConnectivity(MainActivity.this).subscribe(new Consumer() {
@Override
public void accept(@NonNull Connectivity connectivity) throws Exception {
if (connectivity.getState() == NetworkInfo.State.CONNECTED) {
Toast.makeText(MainActivity.this,"RxJava检测到网络已连接",Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(MainActivity.this,"RxJava检测到网络已断开",Toast.LENGTH_LONG).show();
}
}
});
看了这种实现,你还会去继承BroadcastReciver,然后去Manifests.xml里面注册吗?然后通过接口回调?太麻烦了。去试试这种简单明了的方式吧。
七、权限管理管理
RxPermissions地址
compile 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar'
RxPermissions rxPermissions=new RxPermissions(this);
RxView.clicks(findViewById(R.id.getPermissionBtn))
.compose(rxPermissions.ensure(Manifest.permission.WRITE_EXTERNAL_STORAGE))
.subscribe(
new Consumer() {
@Override
public void accept(@NonNull Boolean aBoolean) throws Exception {
if (aBoolean) Toast.makeText(MainActivity.this,"已获取该权限",Toast.LENGTH_LONG).show();
else Toast.makeText(MainActivity.this,"无法获取该权限",Toast.LENGTH_LONG).show();
}
}
);
演示中之所以“无法获取该权限”,是因为没有在配置文件Manifests.xml中申请权限,一旦配置了该权限即返回true。另外,RxPermissions的主要用于Android6.0动态申请权限,通过对话框获取用户授权,而演示模拟器低于Android6.0,所以没有弹出对话框。
至此 ,上面所有的代码及其效果都给大家展示了,相信大家都学会了使用。如果有什么疑问,可以查看我提供的源码Demo。下一篇,我将介绍安卓领域网络请求框架中的宇宙大帝–Retrofit。拭目以待吧。。。
点此下载源码