RxAndroid 基础

一、RxJava 到底是什么

1、一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库

2、RxJava 的优势也是简洁,但它的简洁的与众不同之处在于,随着程序逻辑变得越来越复杂,它依然能够保持简洁。

3、RxJava使我们很方便的使用链式编程,代码看起来既简洁又优雅。但是RxJava使用起来也是有副作用的,使用越来越多的订阅,内存开销也会变得很大,稍不留神就会出现内存溢出的情况。

二、RxJava和EventBus的区别

1、RxJava要比EventBus的应用更广泛,EventBus仅仅是作为一种消息的传递工具,但是RxJava里面几乎可以做任何事情。如果是Android开发的话,可以使用RxAndroid,这是对RxJava的一个扩展,结合sqare公司的retrofit可以很轻松的完成网络的访问。

2、在Android中异步操作一般使用AsycTask来完成,但是AsycTask有很多缺点,如不能方便的终止任务的执行等。RxAndroid完全可以替代AsycTask来完成各种异步操作,而且还有BindActivity和BindFragment方法,你根本不需要考虑异步操作时的Activity和Fragment的生命周期问题,还有更加强大的的链式调用,可以使程序很简洁。

 

三、相关文章

1、RxAndroid的使用方法
    compile?'io.reactivex:rxandroid:1.2.0'
2、如何查看RxAndroid最新版本?
    https://search.maven.org/search?q=a:rxandroid

====总体概念====
给初学者的RxJava2.0教程
给 Android 开发者的 RxJava 详解
通过 RxJava 实现一个 Event Bus – RxBus        RxDownload


====应用场景====
https://github.com/amitshekhariitbhu/RxJava2-Android-Samples
https://github.com/THEONE10211024/RxJavaSamples
https://blog.csdn.net/theone10211024/article/details/50435325

https://github.com/nanchen2251/RxJava2Examples


====操作符====
值得收藏的图解Rxjava Operators    RxJava2牛X到不行的操作符
事件流基础之 过滤数据

 

 

四、如何使用

(一)、部分特点

    1、观察者两种创建方式:

        A:Subscriber继承Observer, 只是 Subscriber对Observer做了一些扩展。Subscriber的使用和Observer完全一样。

        B:onStart(): 这是Subscriber 增加的方法。它会在 subscribe 刚开始,而事件还未发送之前被调用,可以用于做一些准备工作,例如数据的清零或重置。这是一个可选方法,默认情况下它的实现为空。需要注意的是,如果对准备工作的线程有要求(例如弹出一个显示进度的对话框,这必须在主线程执行), onStart() 就不适用了,因为它总是在 subscribe 所发生的线程被调用,而不能指定线程。要在指定的线程来做准备工作,可以使用 doOnSubscribe() 方法。

    2、被观察者创建方式:

        //create方式
        //just方式  最多支持10个数据
        //from方式
         //1:集合
         //2:数组

    3、订阅:

        A:在subscribe() 中,首先会调用 onStart() 方法,这个方法前文已经介绍了,是可选的。接着会调用 call()方法,我们已经分析了在call()方法中会调用多次 onNext() ,最后调用 onCompleted().看到这里你就会突然明白原来subscribe() 方法其实相当于依次执行了:onStart() --> onNext()--> onCompleted()
        B:从这也可以看出,在 RxJava 中,Observable 并不是在创建的时候就立即开始发送事件,而是在它被订阅的时候,即当 subscribe() 方法执行的时候
        C:Observer 和 Subscriber 具有相同的角色,而且 Observer 在 subscribe() 过程中最终会被转换成 Subscriber对象
        D:将传入的 Subscriber 作为 Subscription 返回。这是为了方便 unsubscribe().   

(二)、操作符的使用

        1、Observable.merge操作符,合并观察对象
        2、Observable.zip  操作符,合并多个观察对象的数据。并且允许 Func2()函数重新发送合并后的数据
        3、Observable.scan累加器操作符的使用
        4、Observable.filter 过滤操作符的使用
        5、消息数量过滤操作符的使用   
            take :取前n个数据
            takeLast:取后n个数据
            first 只发送第一个数据
            last 只发送最后一个数据
            skip() 跳过前n个数据发送后面的数据
            skipLast() 跳过最后n个数据,发送前面的数据
        6、elementAt 、elementAtOrDefault
        7、startWith() 插入数据
        8、delay操作符,延迟数据发送
        9、Timer  延时操作符的使用
            相同点:delay 、 timer 都是延时操作符。
            不同点:delay  延时一次,延时完成后,可以连续发射多个数据。timer延时一次,延时完成后,只发射一次数据。
        10、interval 轮询操作符,循环发送数据,数据从0开始递增
        11、doOnNext() 操作符,在每次 OnNext() 方法被调用前执行
        12、Buffer 操作符
            Buffer( int n )      把n个数据打成一个list包,然后再次发送。
            Buffer( int n , int skip)   把n个数据打成一个list包,然后跳过第skip个数据。
        13、throttleFirst 操作符
            在一段时间内,只取第一个事件,然后其他事件都丢弃。
            使用场景:1、button按钮防抖操作,防连续点击   2、百度关键词联想,在一段时间内只联想一次,防止频繁请求服务器 
        14、distinct    过滤重复的数据
            distinctUntilChanged()  过滤连续重复的数据
        15、debounce() 一段时间内没有变化,就会发送一个数据。
            使用场景:百度关键词联想提示。在输入的过程中是不会从服务器拉数据的。
            当输入结束后,在400毫秒没有输入就会去获取数据。避免了,多次请求给服务器带来的压力。在输出了一个数据后的一段时间内,没有再次输出新的数据,则把这个数据真正的发送出去;假如在这段时间内有新的数据输出,则以这个数据作为将要发送的数据项,并且重置这个时间段,重新计时
        16、doOnSubscribe() 
            使用场景: 可以在事件发出之前做一些初始化的工作,比如弹出进度条等等
            注意:
            1、doOnSubscribe() 默认运行在事件产生的线程里面,然而事件产生的线程一般都会运行在 io 线程里。那么这个时候做一些,更新UI的操作,是线程不安全的。
                所以如果事件产生的线程是io线程,但是我们又要在doOnSubscribe() 更新UI , 这时候就需要线程切换。
            2、如果在 doOnSubscribe() 之后有 subscribeOn() 的话,它将执行在离它最近的 subscribeOn() 所指定的线程。   
            3、 subscribeOn() 事件产生的线程 ; observeOn() : 事件消费的线程
        17、range 操作符的使用 
            Range操作符发射一个范围内的有序整数序列,你可以指定范围的起始和长度。
            RxJava将这个操作符实现为range函数,它接受两个参数,一个是范围的起始值,一个是范围的数据的数目。如果你将第二个参数设为0,将导致Observable不发射任何数据(如果设置为负数,会抛异常)。
            range默认不在任何特定的调度器上执行。有一个变体可以通过可选参数指定Scheduler。
        18、defer 操作符

五、Rxjava使用过程中应该注意的事项

(一)、取消订阅

    subscription.unsubscribe() ;可以使用 isUnsubscribed() 先判断一下状态。

    最好保持一个原则:要在不再使用的时候尽快在合适的地方(例如 onPause() onStop() 等方法中)调用 unsubscribe() 来解除引用关系,以避免内存泄露的发生


(二)、线程调度

两种控制Rxjava生命周期的方式,第一种:取消订阅 ;第二种:线程切换
    1:Scheduler调度器,相当于线程控制器
    Schedulers.immediate() : 直接在当前线程运行,相当于不指定线程。这是默认的 Scheduler。
    Schedulers.newThread() :总是启用新线程,并在新线程执行操作.
    Schedulers.io():I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程。
    Schedulers.computation() : 计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在 computation() 中,否则 I/O 操作的等待时间会浪费 CPU。
    还有RxAndroid里面专门提供了AndroidSchedulers.mainThread(),它指定的操作将在 Android 主线程运行。

    2:常见的场景:为了不阻塞UI,在子线程加载数据,在主线线程显示数据
        A、Observable.just( "1" , "2" , "3" )
            .subscribeOn(Schedulers.io())  //指定 subscribe() 发生在 IO 线程
            .observeOn( AndroidSchedulers.mainThread() )  //指定 Subscriber 的回调发生在主线程
            .subscribe(new Action1<String>() {
                @Override
                public void call(String s) {
                    textView.setText( s );
                }
            }) ;
        上面这段代码,数据"1"、"2"、"3"将在io线程中发出,在android主线程中接收数据。这种【后台获取数据,前台显示数据】模式适用于大多数的程序策略。

        B、Scheduler 自由多次切换线程。恩,这个更为牛逼
            Observable.just(1, 2, 3, 4) // IO 线程,由 subscribeOn() 指定
             .subscribeOn(Schedulers.io())
             .observeOn(Schedulers.newThread())
             .map(mapOperator) // 新线程,由 observeOn() 指定
             .observeOn(Schedulers.io())
             .map(mapOperator2) // IO 线程,由 observeOn() 指定
             .observeOn(AndroidSchedulers.mainThread) 
             .subscribe(subscriber);  // Android 主线程,由 observeOn() 指定
            observeOn() 可以调用多次来切换线程,observeOn 决定他下面的方法执行时所在的线程。
            subscribeOn() 用来确定数据发射所在的线程,位置放在哪里都可以,但它是只能调用一次的。


(三)、rxlifecycle 框架的使用

    1、github地址: https://github.com/trello/RxLifecycle
        compile 'com.trello:rxlifecycle-components:0.6.1'

    2、让你的activity继承RxActivity,RxAppCompatActivity,RxFragmentActivity
        让你的fragment继承RxFragment,RxDialogFragment;
    
    3、下面的代码就以RxAppCompatActivity举例
        bindToLifecycle() 方法可以使Observable发布的事件和当前的Activity绑定,实现生命周期同步。也就是Activity 的 onDestroy() 方法被调用后,Observable 的订阅关系才解除。
        在子类使用Observable中的compose操作符,调用,完成Observable发布的事件和当前的组件绑定,实现生命周期同步。从而实现当前组件生命周期结束时,自动取消对Observable订阅。
        
        public class MainActivity extends RxAppCompatActivity {
            TextView textView ;
            
            @Override
            protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            textView = (TextView) findViewById(R.id.textView);
        
            //循环发送数字
            Observable.interval(0, 1, TimeUnit.SECONDS)
                .subscribeOn( Schedulers.io())
                .compose(this.<Long>bindToLifecycle())   //这个订阅关系跟Activity绑定,Observable 和activity生命周期同步
                .observeOn( AndroidSchedulers.mainThread())
                .subscribe(new Action1<Long>() {
                    @Override
                    public void call(Long aLong) {
                        System.out.println("lifecycle--" + aLong);
                        textView.setText( "" + aLong );
                    }
                });
           }
        }
        上面的代码是Observable循环的发送数字,并且在textview中显示出来
        A、没加 compose(this.<Long>bindToLifecycle()) 当Activiry 结束掉以后,Observable还是会不断的发送数字,订阅关系没有解除
        B、添加compose(this.<Long>bindToLifecycle()) 当Activity结束掉以后,Observable停止发送数据,订阅关系解除。

    4、指定在Activity其他的生命状态和订阅关系保持同步,就是 bindUntilEvent()方法。

        bindUntilEvent( ActivityEvent event)
        ActivityEvent.CREATE: 在Activity的onCreate()方法执行后,解除绑定。
        ActivityEvent.START:在Activity的onStart()方法执行后,解除绑定。
        ActivityEvent.RESUME:在Activity的onResume()方法执行后,解除绑定。
        ActivityEvent.PAUSE: 在Activity的onPause()方法执行后,解除绑定。
        ActivityEvent.STOP:在Activity的onStop()方法执行后,解除绑定。
        ActivityEvent.DESTROY:在Activity的onDestroy()方法执行后,解除绑定。

        //循环发送数字
        Observable.interval(0, 1, TimeUnit.SECONDS)
             .subscribeOn( Schedulers.io())
             .compose(this.<Long>bindUntilEvent(ActivityEvent.STOP ))   //当Activity执行Onstop()方法是解除订阅关系
             .observeOn( AndroidSchedulers.mainThread())
             .subscribe(new Action1<Long>() {
                 @Override
                 public void call(Long aLong) {
                     System.out.println("lifecycle-stop-" + aLong);
                     textView.setText( "" + aLong );
                 }
             });
        经过测试发现,当Activity执行了onStop()方法后,订阅关系已经解除了。
    5、在Fragment里面,订阅事件与Fragment的生命周期同步
        FragmentEvent 这个类是专门处理订阅事件与Fragment生命周期同步的大杀器
        public enum FragmentEvent {
            ATTACH,
            CREATE,
            CREATE_VIEW,
            START,
            RESUME,
            PAUSE,
            STOP,
            DESTROY_VIEW,
            DESTROY,
            DETACH
        }
        可以看出FragmentEvent 和 ActivityEvent 类似,都是枚举类


            
            
            
            
            
            
            

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值