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

运行效果
这里写图片描述

二、监听内容变化

不需要重写EditText控件的textWacher,然后写一大堆代码了,看看下面是如何优雅的实现的。
监听单个输入框内容

RxTextView.textChanges(et1).skip(1).subscribe(new Consumer<CharSequence>() {
            @Override
            public void accept(CharSequence charSequence) throws Exception {
                if (TextUtils.isEmpty(charSequence.toString())) enableButton(btn1,false,0.2f);
                else enableButton(btn1,true,1f);
            }
        });

监听多个输入框内容

Observable<CharSequence> ob1= RxTextView.textChanges(et2).skip(1);
        Observable<CharSequence> ob2= RxTextView.textChanges(et3).skip(1);
        Observable.combineLatest(ob1, ob2, new BiFunction<CharSequence, CharSequence, Boolean>() {
            @Override
            public Boolean apply(CharSequence charSequence, CharSequence charSequence2) throws Exception {
                return !TextUtils.isEmpty(charSequence) && !TextUtils.isEmpty(charSequence2);//返回值可以自定义,比如至少6位
            }
        }).subscribe(new Consumer<Boolean>() {
            @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<Long>() {
                            @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<Long>() {
                            @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<Connectivity>() {
            @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<Boolean>() {
                    @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。拭目以待吧。。。

点此下载源码

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
感谢您的提问。要实现指南针功能,我们需要使用Android的Sensor(传感器)API。下面是一些基本步骤: 1. 获取SensorManager对象。您可以通过以下方式获取: ```java SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); ``` 2. 获取方向传感器。我们需要使用Android设备上的方向传感器来获取设备的方向。您可以使用以下代码获取方向传感器: ```java Sensor orientationSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); ``` 请注意,`Sensor.TYPE_ORIENTATION`在Android API级别20被弃用。您应该使用`Sensor.TYPE_ROTATION_VECTOR`代替。 3. 创建SensorEventListener。我们需要实现`SensorEventListener`接口来接收传感器数据。您可以使用以下代码来创建一个SensorEventListener: ```java private final SensorEventListener sensorEventListener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { // 当传感器数据更新时调用此方法 // 在这里更新指南针方向 } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // 当传感器精度发生变化时调用此方法 } }; ``` 4. 注册SensorEventListener。您需要在Activity的生命周期方法(例如`onResume()`)注册`SensorEventListener`,以便在传感器数据更新时接收通知。您可以使用以下代码进行注册: ```java sensorManager.registerListener(sensorEventListener, orientationSensor, SensorManager.SENSOR_DELAY_UI); ``` 请注意,`SENSOR_DELAY_UI`表示传感器数据应该以与UI线程更新相同的频率更新。您可以使用其他常量来指定更新频率。 5. 实现指南针方向。您需要使用传感器数据来计算设备的方向,并更新指南针方向。您可以使用以下代码来获取设备的方向: ```java float[] orientationValues = new float[3]; SensorManager.getOrientation(event.values, orientationValues); float azimuth = Math.toDegrees(orientationValues[0]); ``` 请注意,`azimuth`表示设备的方向,以度为单位。 6. 更新指南针方向。您需要在UI线程更新指南针方向。您可以使用以下代码来更新指南针方向: ```java runOnUiThread(new Runnable() { @Override public void run() { compassView.setDirection(azimuth); } }); ``` 请注意,`compassView`是一个自定义视图,用于绘制指南针。 这些是实现指南针功能的基本步骤。您需要根据自己的需求进行调整和修改。祝您好运!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值