RxAndroid和Retrofit结合使用-网络调用和生命周期分析
来源:互联网 发布:淘宝商品类目大全 编辑:程序博客网 时间:2024/06/05 06:43
说明
这是我在项目使用RxAndroid、RxJava和Retrofit时的一些记录和分析。
记录1:
网络操作相关
在使用RxAndroid和Retrofit进行网络操作时,有如下这些代码
代码:
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类里面层层调用最后能看到这样的代码
// 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 行为。
资料来自于:
https://segmentfault.com/a/1190000004077117?utm_source=tuicool&utm_medium=referral
记录2:
有关网络调用和生命周期
代码:
修改上面的代码,添加线程休眠2秒,网络操作在onActivityCreated生命周期中调用
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(只有响应操作的打印...)
打印结果:
(进入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用于统一管理。
代码:
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(四:响应式安卓开发)的原文中又提到
这样的代码实现
AndroidObservable.bindActivity(this, retrofitService.getImage(url)) .subscribeOn(Schedulers.io()) .subscribe(bitmap -> myImageView.setImageBitmap(bitmap);
实现:当你的Activity或Fragment完成,同样也会发出停止网络操作信号
这里有AndroidObservable源码
但是相信大家在compile 'io.reactivex:rxandroid:1.1.0'
- 编译之后是找不到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.
最后:
- 官方推荐的RxLifecycle来管理生命周期,个人觉得RxLifecycle太死板,它需我们继承
extends RxAppCompatActivity
,会影响我们的代码层级。 - Check whether you need to add observeOn(AndroidSchedulers.mainThread()) to the sequence.,好好写代码吧。
- 目前使用CompositeSubscription来管理订阅者的订阅是比较常见的做法。当然是在有需要的情况下使用。
- RxAndroid和Retrofit结合使用-网络调用和生命周期分析
- rxjava 和retrofit 结合使用 请求网络
- Retrofit与RxAndroid结合使用
- Retrofit和RxJava结合使用例子分析
- Android RxJava/RxAndroid结合Retrofit使用
- Retrofit 和 RxJava 结合使用
- Retrofit和RxJava结合使用
- RxJava和Retrofit结合使用
- RxJava和Retrofit结合使用
- rxjava 和retrofit 结合使用
- RxJava和Retrofit结合使用详解
- Retrofit和RxJava的结合使用
- Rxjava和Retrofit结合使用的案例
- Retrofit 和 Rxjava 的结合使用
- 结合retrofit和rxjava的使用
- RxJava RxAndroid Retrofit实践结合
- Retrofit和Rxandroid的整合网络工具类
- rxjava和retrofit结合
- 容斥原理的学习
- 1.8.1 Nginx+Tomcat实现单IP、多域名、多站点的访问
- 算法_动态规划_01背包问题(重量为浮点型)
- Memcached安装与配置
- zoj3872——Beauty of Array(数学)
- RxAndroid和Retrofit结合使用-网络调用和生命周期分析
- (第11讲)二分排序(折半插入排序法)
- IOS-dispatch_once和@synchronized的单例区别
- 苹果双系统安装教程,苹果笔记本如何装Win7(经典)
- Android的UEvent流程分析
- 生成二维码的简单示例
- Python 资源大全
- 图像亮度自适应调整
- IOS开发证书 钥匙串“此证书的签发者无效”解决方法