在RxJava中,Observable被订阅后,可以得到一个Disposable对象。为了防止内存泄露,一般情况下,都会在Activity结束的时候调用Disposable对象的dispose()方法,解除订阅。
RxJava2中,提供了一个CompositeDisposable类作为Disposable的容器。
1 | public final class CompositeDisposable implements Disposable, DisposableContainer { |
可以看出,CompositeDisposable实现了Disposable接口(void dispose();方法);实现了DisposableContainer接口,可以add、remove、delete操作Disposable。
重点要关注两个方法:
1、add(@NonNull Disposable d)
这个方法是将一个dispoable加入CompositeDisposable中,当Activity或者Fragment的生命周期结束的时候,通过
dispose()方法将Observable的订阅事件取消关联,防止内存泄露。
2、public void dispose()
这个方法就是CompositeDisposable中将所有的Observable的订阅事件取消关联使用。
之前遇到过一个问题:
使用MVP模式开发的时候,Activity A的Presenter中包含CompositeDisposable对象,Activity A的onStart()方法中关联了A的Presenter,当Activity A 跳转到Activity B的时候,我在A的onStop()方法中调用了CompositeDisposable.dispose()方法。当Activity B 调用finish()方法结束时候,回到Activity A页面,Activity A上的所有关于RxJava的调用都失效。
我通过Debug的方式一层层的查看方法的调用栈对比正常的情况,最终发现:
CompositeDisposable的dispose()方法在被调用之后,所有的add()进来的Disposable都会直接调用自身的dispose()方法,也就是说在事件刚被绑定监听的时候就被解除绑定了。
查看源码:
1 |
|
在dispose() 方法调用的时候,会将全局变量disposed
置为true。
再看add方法:
1 |
|
在add一个disposable的时候,如果全局变量disposed为true,那么不会走if条件,而是直接走下面的d.dispose();
这句,直接将监听的事件解除绑定。
所有,CompositeDisposable的dispose()方法一定要放到Activity和Fragment生命周期结束的地方——onDestroy()中。