在Android ViewModel中何时及如何处理RxJava2的Disposable?
在ViewModel中处理RxJava Disposable的正确姿势
首先明确说:完全有必要处理Disposable,别抱有侥幸心理。ViewModel的生命周期比普通Activity/Fragment要长——比如屏幕旋转时,Activity会销毁重建,但ViewModel会被保留下来。如果你的Disposable没及时处置,不仅可能导致内存泄漏,还会让订阅继续跑,比如还在请求网络或者监听数据,这既浪费资源又可能引发奇怪的bug。
那该什么时候处理呢?ViewModel自带了一个专门的回调方法:onCleared()。这个方法会在ViewModel真正被销毁的时候调用(比如用户退出页面,Activity彻底被销毁,而不是旋转这种临时重建的情况),这就是我们处置Disposable的最佳时机。
具体怎么操作?推荐用RxJava的CompositeDisposable来统一管理所有的Disposable,这样不用一个个单独处理,省心又不容易漏:
public class MyViewModel extends ViewModel { private CompositeDisposable compositeDisposable = new CompositeDisposable(); public void fetchData() { // 假设这是一个RxJava订阅 Disposable disposable = someDataSource.fetch() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(data -> { // 处理数据 }, error -> { // 处理错误 }); // 将Disposable加入CompositeDisposable管理 compositeDisposable.add(disposable); } @Override protected void onCleared() { super.onCleared(); // 清空所有Disposable,终止所有订阅 compositeDisposable.clear(); // 或者用dispose(),区别是clear()之后还可以继续add新的Disposable,dispose()之后就不能用了 // compositeDisposable.dispose(); } }
这里要注意和Activity的onDestroy()区分开:Activity的onDestroy()在屏幕旋转时也会触发,但这时候ViewModel还活着,如果在Activity里处理ViewModel的Disposable,会导致正常的订阅被提前终止,反而出问题。所以一定要把Disposable的处置逻辑放在ViewModel自己的onCleared()方法里,让ViewModel自己管理自己的订阅生命周期。
总结一下:
- 必须处理Disposable,避免内存泄漏和无效订阅
- 时机:重写ViewModel的
onCleared()方法 - 方式:用
CompositeDisposable统一管理,在onCleared()中调用clear()或dispose()
内容的提问来源于stack exchange,提问作者Micer
相关产品推荐
相关产品推荐

