CompositeDisposable

    • 一、Disposable
      • 1、简介
      • 2、调用
        • 2.1、主动解除订阅
        • 2.2、查询是否解除订阅 true 代表 已经解除订阅
        • 2.3、栗子
        • 2.4、取消订阅的操作,有必要在链路中使用吗?
        • 2.5、关于内存泄漏
        • 2.6、关于 dispose 的实时性
    • 二、CompositeDisposable
      • 1、简介
      • 2、调用
        • 2.1、实例化
        • 2.2、将disposable添加到容器中
        • 2.3、将disposable从容器中删除
        • 2.4、取消所有订阅
        • 2.5、取消disposable并从容器移除
        • 2.6、取消所有订阅,并不再接收新订阅
    • 三、举例封装
      • 1、针对像网络请求的功能模块,网络请求集体取消后续的需求进行封装
      • 2、一般场景的使用
  • 参考地址

一、Disposable

1、简介

rxjava虽然好用,但是总所周知,容易遭层内存泄漏。也就说在订阅了事件后没有及时取阅,导致在activity或者fragment销毁后仍然占用着内存,无法释放。而disposable便是这个订阅事件,可以用来取消订阅。

2、调用

2.1、主动解除订阅

dispose():

注:切断观察者 与 被观察者 之间的连接,不会影响正在执行的Observer部分代码的调用

2.2、查询是否解除订阅 true 代表 已经解除订阅

isDisposed():

2.3、栗子


Disposable disposable;Observable.timer(100, TimeUnit.MILLISECONDS, Schedulers.io()).observeOn(Schedulers.io()).subscribe(new Observer<Long>() {@Overridepublic void onSubscribe(Disposable d) {disposable = d;}@Overridepublic void onNext(Long aLong) {LogUtils.i(TAG, "write ... again");write();}@Overridepublic void onError(Throwable e) {}@Overridepublic void onComplete() {}//取消时
disposable.dispose();

2.4、取消订阅的操作,有必要在链路中使用吗?

其实还是有必要的,但是需要根据需求来。

比如,我需要在 void onNext(Long aLong) 方法中做一些操作,如果上面下发的数据满足条件,我就注销链路。

那么需要在 onComplete() 和 onError(Throwable e)方法中调用吗? 无需,因为他们已经调用了。

ObservableCreate中:

        @Overridepublic boolean tryOnError(Throwable t) {if (t == null) {t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");}if (!isDisposed()) {try {observer.onError(t);} finally {dispose();}return true;}return false;}@Overridepublic void onComplete() {if (!isDisposed()) {try {observer.onComplete();} finally {dispose();}}}

2.5、关于内存泄漏

调用dipose确实可以终止数据流,但是不等于没有内存泄露。
查看 ObservableCreate 的源码可知,dispose只是简单地设置了 DISPOSED 状态,Observe 中关联的上下游对象并没有释放。所以当订阅了静态的 Observable 时,无法避免内存泄漏。

但是当订阅一个 Subject 时,dispose 确实可以有效释放对象,避免内存泄漏:

public void dispose() {if (super.tryDispose()) {parent.remove(this); //对象删除}
}

转自 详解 RxJava 的 Disposable:https://developer.aliyun.com/article/940680

2.6、关于 dispose 的实时性

前面分析知道,对于终端操作符 create、subscribe 等,其 Observer 在 dispose 时会标记当前状态为 DISPOSED。但对于其他操作符的 dispose 只是递归向上调用 parent 的 dispose 而已,并没有 DISPOSED 状态的设置,也就不会拦截发射中的数据。

调用dispose后,RxJava数据流不一定会立即停止,大部分操作符在调用 dispose 后,数据依然会发射给下游
关于 dispose 的实时性测试,下文可供参考

https://medium.com/stepstone-tech/the-curious-case-of-rxjava-disposables-e64ff8a06879

转自 详解 RxJava 的 Disposable:https://developer.aliyun.com/article/940680

二、CompositeDisposable

1、简介

一个disposable的容器,可以容纳多个disposable,添加和去除的复杂度为O(1)。

作用:管理订阅事件disposable。

注意:如果这个CompositeDisposable容器已经是处于dispose的状态,那么所有加进来的disposable都会被自动切断。

2、调用

2.1、实例化

compositeDisposable = new CompositeDisposable();

2.2、将disposable添加到容器中

CompositeDisposable.add()

如果容器已经 调用过 void dispose()方法,就不再接受新的添加

2.3、将disposable从容器中删除

CompositeDisposable.delete(disposable);

一般不直接调用,这个方法只是删除 CompositeDisposable 中,

OpenHashSet resources; 中存的 disposable 数据,不会进行 disposable.dispose

2.4、取消所有订阅

compositeDisposable.clear();

调用此方法,后续还可以继续向 CompositeDisposable 中添加数据: compositeDisposable.add()

2.5、取消disposable并从容器移除

使用 remove 方法,remove可以从 OpenHashSet resources; 内部容器把数据移除,然后再取消订阅,注意的是如果移除失败是不会进行取消的,要注意此方法只适用了disposable加入到compositeDisposable中

    @Overridepublic boolean remove(@NonNull Disposable disposable) {if (delete(disposable)) {disposable.dispose();return true;}return false;}

2.6、取消所有订阅,并不再接收新订阅

compositeDisposable.dispose 会取消所有订阅,并不接收新订阅,这点区别于remove

    @Overridepublic void dispose() {if (disposed) {return;}OpenHashSet<Disposable> set;synchronized (this) {if (disposed) {return;}disposed = true;set = resources;resources = null;}dispose(set);}

三、举例封装

1、针对像网络请求的功能模块,网络请求集体取消后续的需求进行封装

public class RxJavaGcManager {private static RxJavaGcManager instance;private RxJavaGcManager() {}public static RxJavaGcManager getInstance() {if (instance == null) {instance = new RxJavaGcManager();}return instance;}private CompositeDisposable compositeDisposable;public void add(Disposable disposable) {if (compositeDisposable == null) {compositeDisposable= new CompositeDisposable();}compositeDisposable.add(disposable);}public void clearDisposable() {if (compositeDisposable != null) {compositeDisposable.clear();}}

调用:

RxJavaGcManager的clearDisposable方法取消所有订阅

2、一般场景的使用

如页面业务逻辑的订阅,我认为自己创建自己的管理类,比较容易管理

当然也可以使用Map管理CompositeDisposable 的形式对应个业务页面

public class RxRecycleUtil {private CompositeDisposable compositeDisposable;public RxRecycleUtil() {compositeDisposable = new CompositeDisposable();}/*** 加入 compositeDisposable 管理** @param disposable -*/public void add(Disposable disposable) {if (disposable != null) {compositeDisposable.add(disposable);}}/*** 已经加入 compositeDisposable 中的 disposable 如此取消** @param disposable -*/private boolean remove(Disposable disposable) {if (compositeDisposable != null) {return compositeDisposable.remove(disposable);} else {return false;}}/*** 取消所有*/public void clear() {if (compositeDisposable != null) {compositeDisposable.clear();compositeDisposable = null;}}/*** 没有 加入 compositeDisposable 中的 disposable 如此取消** @param disposable -*/public void disposable(Disposable disposable) {if (disposable != null && !disposable.isDisposed()) {disposable.dispose();}}}

参考地址

CompositeDisposable:https://blog.csdn.net/weixin_43724742/article/details/102991355

详解 RxJava 的 Disposable:https://developer.aliyun.com/article/940680

每天记录学习的新知识 : Disposable和CompositeDisposable相关推荐

  1. 每天记录学习的新知识:开源代码是否可以商用在项目中?

    开源代码是否可以商用? 是否可以商用? 如何查看许可证是哪个? 什么是 Apache License 2.0 ? 如何使用开源代码? 1.根路径添加 LICENSE 文件 2.根路径添加 NOTICE ...

  2. 每天记录学习的新知识 :WebView介绍以及基本使用和方法

    WebView介绍以及基本使用和方法 一.简介 二.调用: 三.方法介绍 3.1 WebView状态控制 3.2 WebView销毁和清理 3.3 WebView网页切换 3.4 WebView的回调 ...

  3. 每天记录学习的新知识 :Navigation

    Navigation 前言 Navigation Activity 多个Fragment的情况 Fragment 嵌套 Fragment 参考地址 前言 Jetpack 是一个丰富的组件库,它的组件库 ...

  4. 每天记录学习的新知识:圆的运算公式

    前言: 对于圆的运算,忘记得很彻底,回顾一下. 公式: 圆的周长,C=2πr 或 C=πd 圆的面积,S=πr2=πd2/4 弧度 1弧度约为57.3°,即57°17'44.806'',1°为π/18 ...

  5. 每天记录学习的新知识:ContentResolver

    ContentResolver 一.用途 二.方法 三.使用 1.查询 2.插入 3.数据刷新通知 4.可以用于监听系统的数据变化 参考地址 一.用途 ContentResolver直译为内容解析器, ...

  6. 每天记录学习的新知识 : gilde 和 picasso的区别

    区别和联系 1.Context 不同 Picasso.with(只能传入上下文) . Glide.with,后面可以传入上下文,activity实例,FragmentActivity实例,Fragem ...

  7. 每天记录学习的新知识:利用高德地图绘制历史路线

    前提: App需要展示行程路线,这里用的是高德地图的Api 绘制路线: 首先下载了官方提供的 AMap3DDemo ,运行后找到 case 多彩线绘制,仿照它基本上可以实现路线绘制. 绿色位置请忽略. ...

  8. 【每天学习一点新知识】中间人攻击是什么

    目录 中间人攻击介绍 中间人攻击原理 1. ARP欺骗 2. DNS欺骗 防御方法 中间人攻击介绍 中间人攻击(man-in-the-middle attack, abbreviated to MIT ...

  9. 每天学习一点新知识(一)——Unity开发游戏的拆包

    每天学习一点新知识(一)--Unity开发游戏的解包 用了CSDN有一段时间了,但一直都没有写过blog,只是在输入,没有输出.而且一直主要都是在查一些作业.题解什么的,还是希望自己能够多学到一些新东 ...

最新文章

  1. 【126】TensorFlow 使用皮尔逊相关系数找出和标签相关性最大的特征值
  2. iOS 成员变量的作用范围
  3. OpenCV函数 Canny 检测边缘
  4. 百度母婴技术团队—基于Reactjs实现webapp #1
  5. Apache开源项目
  6. hdc和hwnd的区别
  7. Android利用Jsoup解析html 开发网站客户端小记。
  8. 图论算法在机试实现中的一些技巧和陷阱
  9. WebDriver API 实例详解(二)
  10. jdk LinkedHashMap源码分析
  11. JAVA集合系列(4):关于数组复制的几种方法(源码解读)及执行效率,我们知多少?
  12. 微软2022年10月补丁周二修复了84个漏洞
  13. VS2019安装和使用教程
  14. erp352产品安装手册
  15. 吉林省等保测评机构项目测评收费价格标准参考
  16. java 发送邮件demo_java邮件发送Demo(完整例子)
  17. 手机产业未来的发展方向
  18. win进程崩溃弹出Microsoft Visual C++ Runtime Library的解决办法
  19. OrientedRepPoints_DOTA环境搭建训练流程及问题
  20. SAP SD V/LD标准定价报表配置

热门文章

  1. 1709 ltsb 内存占用_「正点原子STM32Mini板资料连载」第三十二章 内存管理实验
  2. 尚硅谷-宋红康-JVM上中下篇完整笔记-JVM上篇_内存与垃圾回收篇
  3. 微电流检测芯片_什么是微芯片价值?
  4. 做地推真能赚到钱,第一单我赚了200元
  5. 几招教你最简单的网站站内优化
  6. 利用CE修改内存方法通关
  7. 王下邀月熊_Chevalier的前端每周清单系列文章索引
  8. SpringMVC转发与重定向的区别
  9. 计算机控制网络试题,西安交通大学18年9月课程考试《计算机控制技术》作业考核试题【参考答案】...
  10. 如何利用积分兑换商城系统助力积分商城运营