安卓开发进阶之RxJava在实际项目中使用--第一篇

关于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() {
            @Override
            public void accept(Object o) throws Exception {
                Log.d("tvClick","2秒内只能点击一次");
                Toast.makeText(MainActivity.this,"2秒内只能点击一次",Toast.LENGTH_LONG).show();
            }
        }); 
  

运行效果
安卓开发进阶之RxJava在实际项目中使用--第一篇_第1张图片

二、监听内容变化

不需要重写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);
            }
        });

安卓开发进阶之RxJava在实际项目中使用--第一篇_第2张图片
三、延迟操作

     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();
                            }
                        });

安卓开发进阶之RxJava在实际项目中使用--第一篇_第3张图片

四、周期性操作

周期性操作再也不用自带的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()
安卓开发进阶之RxJava在实际项目中使用--第一篇_第4张图片

从上面的运行效果可以看到退出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存在的意义。

安卓开发进阶之RxJava在实际项目中使用--第一篇_第5张图片

六、监听网络状态

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。拭目以待吧。。。

点此下载源码

你可能感兴趣的:(安卓开发进阶系列,安卓经验)