美文网首页Android干货走进android
给android开发者使用rxjava的7个建议

给android开发者使用rxjava的7个建议

作者: brzhang | 来源:发表于2016-07-01 14:46 被阅读436次

    原文地址:http://futurice.com/blog/top-7-tips-for-rxjava-on-android
    翻译:brzhang
    翻译水准:并非一字一句翻译。

    文章的背景

    作者介绍了一段经历,话说他们做了一个大胆的尝试,将他们的android架构使用rxjava重构,结果,遇到了一些问题,大概就是从之前的null pointer 变成了现在的线程问题,然而作者当时也陷入了困境,发现遇到问题了,stackover也似乎帮不上什么忙,但经过几个月的努力,他们依然成功了,重构出了一个可测试性比较好的框架,所以才有了这篇文字吧,总之,虽然说rxjava上手难度是有的,但非常值得试一试!

    预备知识

    首先看一下这个Observer-Operation-Subscriber(我个人认为应该说成是Observable-Operation-Subscriber) 链:

    Paste_Image.png

    比较简单,它表示发送了一个整形5,经过一个Operation 为+2的操作,最后发送7给Subscriber,实际上也是(Observer),要注意这个过程是异步的,也就是说subscriber并不知道原始的那个5已经被加工运算过,其实它认为Observable发送给他的就是7。如果你对函数式编程的概念不了解,那么这里有一篇文章是给你,
    a wide-spread post about Rx

    那么接下来的,将是本文的重点了,也就是rxjava的七个建议。

    • 1. 记住!!rxjava默认是同步的
      也就是说,线程切换交给你来处理。
    • 2. 热冷subscriptions
      通常observables在没有被订阅的时候,称之为冷subscription,是不会执行onSubscribe方法的,只有被订阅之后,才热了,才会执行onSubscribe,以及系列的operation。比如,这个就是冷subscription
      Paste_Image.png
      亦比如 ,这两个是热subscription了。
    Paste_Image.png

    然而,还有更加重要的一点,那就是一个observable是可以被多次订阅的,这是因为,onSubscribe方法会为每个subscriber去独立的执行。那么有没有什么办法保证subscriber接收到其他的subscriber接收过的数据,答案显然是有的,那就是

    • cache
      cache用以下图表示在适合不过了,实际上我是这么理解的,cache有点类似做了一个中间的订阅者subscriber,然后同时它自己又是一个observable,可以给后续的subscriber订阅。


      Paste_Image.png

    作者这里给出了一个应用cache的例子self-contained example

    • 3. 当遇到麻烦的时候,不妨考虑使用subjects
      作者把subjects当做是最后的杀手锏,subjects在适当的时候可以是一个observable,在适当的时候,它又可以是一个subscriber,了解了它,你也就了解了rx的原理,甚至可以用它来处理一些棘手的问题,其中PublishSubject就是一个使用最广泛的家伙,实际上,事件总线比如otto就可以用PublishSubject取代,如果你不明白怎么去做,这里有一个例子:
      RxBus
    • 4. 时刻关注线程问题
      当你需要为observable做部分异步操作的时候,你不得不去关注这个概念,这里只需要你记住一点,耗时操作,比如网络不应该放在ui线程,更新ui线程操作不应该丢在非ui线程。然而关于取消订阅,这个可能是rx需要改进的一点,那就是用户自己写的Observable在onSubscribe方法没有被执行完之前,是不能被取消订阅的,因此这个地方是可能存在性能瓶颈的。

    • **5 . 没有什么比官方文档更靠谱的了,有丰富的图表 **

    这里是官方文档.

    • 6. 订阅的多种方式
      我比较懒,都是写成
    .subscribe(new Subscriber<QueryMatchResponse>() {
        @Override
        public void onCompleted() {
          
        }
    
        @Override
        public void onError(Throwable e) {
       
        }
    
        @Override
        public void onNext(QueryMatchResponse response) {
            
        }
    });
    

    个人觉得,这个地方没有必要太较真。

    • 7. 时刻注意内存泄露
      rx也不是万能的,使用不当,依然会有内存泄露,你在obserable中使用了context吧,当然我一提你就知道,这个时候是用应用context还是使用ui及context,内存泄露说解决也很好解决,关键点就在于,你的activity或者fragment要被回收的时候,是否有人还强引用着它,如果有,那抱歉,你泄露了,如果不存在,OK,他回收成功,不存在泄露。

    作者最后总结,如果你想使用rxjava构建一个android框架,可以参考他的这个示例,这当然是一顿相当不错的午餐咯
    rx-android-architecture

    相关文章

      网友评论

      • 68768b474bfc:同一个subscriber只能订阅一个Observable一次吗?
        brzhang:@TellH 不好意思,比较晚才看到,对于mSubscriber只能执行一次实际上是因为这个mSubscriber在执行一次之后会被unsubscribed掉,而这时候Observable实际上是会检查他的mSubscriber是不是已经unsubscribed掉了,如果没有,才发射的,这一点可以看看源码,有有助于你去理解。因为有多个实现,我就随便举个例子,你可以去看看OnSubscribeFromArray这个类的,fastPath方法。 :grin:
        68768b474bfc:@brzhang 我遇到一个场景:每次下拉刷新都调用一个方法:
        Observable.from(mList).subscribe(mSubscriber);
        如果像这样mSubscriber写成类的字段,这个方法只能执行一次,想刷新执行第二次就不行。
        如果把subscribe()传一个内部类进去,这个方法可以任意执行多次。
        因为Subscriber每次处理的逻辑都一样,每次调用都要生成内部类有点浪费。
        brzhang:@TellH 一般没这么玩,要看业务场景。
      • suphu:你好,楼主,在使用过程中,有遇到网络请求一半,退出Activity造成的Theard泄露吗?已在销毁时调用了un了。
        brzhang:@古半城 我没有遇到过,你是否把所有的Subscription 都 unsubscribe,如果一个页面有多个Subscription,最好是使用CompositeSubscription 统一管理;)

      本文标题:给android开发者使用rxjava的7个建议

      本文链接:https://www.haomeiwen.com/subject/dxnfjttx.html