亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

RxAndroid和Retrofit結合使用-網絡調用和生命周期分析

標簽:
Android

说明

这是我在项目使用RxAndroid、RxJava和Retrofit时的一些记录和分析。

记录1:

网络操作相关

在使用RxAndroid和Retrofit进行网络操作时,有如下这些代码

代码:

[代码]java代码:

?

01

02

03

04

05

06

07

08

09

10

getMyFollowingBoard(mTokenType,   mTokenAccess, mIndex, mLimit)

               .doOnUnsubscribe(new Action0() {

                   @Override

                   public void call() {

                       Logger.d("Unsubscribe");

                   }

               })

               .subscribeOn(Schedulers.io())

               .observeOn(AndroidSchedulers.mainThread())

               .subscribe(只有响应操作的打印...)

打印结果:

(正确联网返回)

[ModuleFragment:onStart:230]: 
[ModuleFragment:onNext:251]: 
[ModuleFragment:onCompleted:236]: 
[ModuleFragment:call:221]: Unsubscribe

分析:

·         网络的调用在Fragment中,没有做相关Fragment生命周期绑定处理。

·         打印结果的前四行,没有问题,是正确的调用。

疑问:

但是我没有在任何地方调用取消订阅的操作,为什么会能够响应doOnUnsubscribe方法?

有必要贴一下doOnUnsubscribe的说明图


方法说明:Observables被取消订阅时候调用。

总结:

在RxJavaCallAdapterFactory类里面层层调用最后能看到这样的代码

[代码]java代码:

?

1

2

3

4

5

6

// Attempt to cancel the call if it is   still in-flight on unsubscription.

      subscriber.add(Subscriptions.create(new Action0() {

        @Override public void call()   {

          call.cancel();//这是Retrofit网络取消方法

        }

      }));

这段代码是给 subscribe 增加一个 unsubscribe 的事件。 也就是请求完成的时候,会自动对 call 进行一个终止,也就是 http 的 close 行为。

记录2:

有关网络调用和生命周期

代码:

修改上面的代码,添加线程休眠2秒,网络操作在onActivityCreated生命周期中调用

[代码]java代码:

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

getMyFollowingBoard(mTokenType,   mTokenAccess, mIndex, mLimit)

 .filter(new Func1<followingboardlistbean, boolean="">()   {

                    @Override

                    public Boolean call(FollowingBoardListBean   followingBoardListBean) {

                        try {

                            Thread.sleep(2000);

                        }   catch (InterruptedException   e) {

                            e.printStackTrace();

                        }

                        return true;

                    }

                })

                .doOnUnsubscribe(new Action0() {

                    @Override

                    public void call() {

                        Logger.d("Unsubscribe");

                    }

                })

                .subscribeOn(Schedulers.io())

                .observeOn(AndroidSchedulers.mainThread())

                .subscribe(只有响应操作的打印...)</followingboardlistbean,>

打印结果:

(进入Fragment,再马上退出)

[BaseFragment:onCreateView:95]: MyAttentionBoardFragment 
[BaseFragment:onActivityCreated:106]: MyAttentionBoardFragment 
—>按下返回键,退出这个Fragment 
[BaseFragment:onPause:124]: MyAttentionBoardFragment 
[BaseFragment:onDestroyView:136]: MyAttentionBoardFragment 
[BaseFragment:onDestroy:143]: MyAttentionBoardFragment 
[MyAttentionBoardFragment:onNext:90]: 
[MyAttentionBoardFragment:onCompleted:79]: 
[MyAttentionBoardFragment:call:70]: Unsubscribe

分析:

·         我在联网的方法中添加了让线程休眠2秒的方法,模拟网络状态不好的情况下,联网结果返回很慢。

·         可以看到,我在onActivityCreated中开始联网,由于延迟在马上退出后,在我整个Fragment都已经销毁,联网结果才返回。

问题:

在负责显示网络内容的Fragment都销毁的情况还接收联网结果调用是没有意义的。没有用的对象占用内存。

解决办法:

在RxJava中存在这个类 
rx.subscriptions.CompositeSubscription

类说明:Subscription that represents a group of Subscriptions that are unsubscribed together. 
All methods of this class are thread-safe. 
翻译:有关于Subscriptions的集合类,用于取消订阅操作。

所以我们可以使用它保存我们的Subscription联网操作,在合适的地方取消 
集成在BaseFragment用于统一管理。

代码:

[代码]java代码:

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

public abstract class BaseFragment   extends Fragment   {

         private CompositeSubscription   mCompositeSubscription;

 

    public CompositeSubscription   getCompositeSubscription() {

        if (this.mCompositeSubscription == null) {

            this.mCompositeSubscription   = new CompositeSubscription();

        }

 

        return this.mCompositeSubscription;

    }

 

    public void addSubscription(Subscription s) {

        if (this.mCompositeSubscription == null) {

            this.mCompositeSubscription   = new CompositeSubscription();

        }

 

        this.mCompositeSubscription.add(s);

    }

 

     @Override

    public void onDestroy() {

        super.onDestroy();

          //在销毁时统一取消

        if (this.mCompositeSubscription != null) {

            this.mCompositeSubscription.unsubscribe();

        }

 

    }

 

}

添加上面代码到BaseFragment后,再次实验

打印结果:

[BaseFragment:onCreateView:95]: MyAttentionBoardFragment 
[BaseFragment:onActivityCreated:106]: MyAttentionBoardFragment 
[BaseFragment:onResume:118]: MyAttentionBoardFragment 
[BaseFragment:onPause:124]: MyAttentionBoardFragment 
[BaseFragment:onDestroy:143]: MyAttentionBoardFragment 
[MyAttentionBoardFragment:call:72]: Unsubscribe //看到取消了 
[BaseFragment:onDetach:155]: MyAttentionBoardFragment

总结:

这样就实现了RxAndroid和Retrofit在Fragment的优化(Activity同理)

这在Goog官方MVP架构中,同样采用这样的方式处理生命周期同步。

记录3

AndroidObservable

在这篇博客http://blog.danlew.net/2014/10/08/grokking-rxjava-part-4/ 
也就是深入浅出RxJava(四:响应式安卓开发)的原文中又提到 
这样的代码实现

[代码]java代码:

?

1

2

3

AndroidObservable.bindActivity(this,   retrofitService.getImage(url))

    .subscribeOn(Schedulers.io())

    .subscribe(bitmap   -> myImageView.setImageBitmap(bitmap);

实现:当你的Activity或Fragment完成,同样也会发出停止网络操作信号

这里有

·         编译之后是找不到AndroidObservable这个类。 http://stackoverflow.com/ 上也有很多问的人,为什么找不到? 同学仔细看原文的发布时间 2014年10月,2年前的博文啊!

原因

·         RxAndroid/wiki明确说到官方已经移除了这个类

AppObservable and its bind methods have been completely eradicated. There were a number of problems with it: 
说明:AppObservable(也就是进化版的AndroidObservable),存在很多问题,已经从RxAndroid中移除

问题如下: 
1. It tried to auto-unsubscribe, but it would only do so if the sequence emitted an item after the Activity or Fragment paused. As a consequence, sequences that never end might never unsubscribe. 
2. It was designed to defend against notifications after pause, but it appears that bug only occurred due to a subtle logic issue in the HandlerScheduler. 
3. It automatically called observeOn(AndroidSchedulers.mainThread()), whether you wanted it or not.

最后:

1.       官方推荐的RxLifecycle来管理生命周期,个人觉得RxLifecycle太死板,它需我们继承extends RxAppCompatActivity,会影响我们的代码层级。

2.       Check whether you need to add observeOn(AndroidSchedulers.mainThread()) to the sequence.,好好写代码吧。

3.       目前使用CompositeSubscription来管理订阅者的订阅是比较常见的做法。当然是在有需要的情况下使用。

原文链接:http://www.apkbus.com/blog-705730-60690.html

點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消