在 RxJava 中,内存泄漏的根本原因通常是:订阅(Subscription / Disposable)没有及时取消,导致 Observer 持有 Activity / Fragment / View 等外部对象,页面销毁后仍被 RxJava 链条引用。
下面从 原理 → 常见场景 → 解决方案 系统说明。
典型泄漏示例:
Observable.timer(10, TimeUnit.SECONDS)
.subscribe(aLong -> {
// 这里持有了 Activity
textView.setText("done");
});
问题:
subscribe 返回的 Disposable 没有管理✅ 核心原则:页面销毁时,取消所有订阅
| 方案 | 适用场景 |
|---|---|
CompositeDisposable |
最常用 |
Disposable 手动 dispose |
简单场景 |
autoDispose |
更现代、自动 |
RxLifecycle |
老项目常见 |
bindToLifecycle |
配合 Activity/Fragment |
| 避免匿名内部类 | 所有场景 |
CompositeDisposablepublic class MyActivity extends AppCompatActivity {
private CompositeDisposable compositeDisposable = new CompositeDisposable();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Disposable disposable = Observable.interval(1, TimeUnit.SECONDS)
.subscribe(t -> Log.d("Rx", "tick"));
compositeDisposable.add(disposable);
}
@Override
protected void onDestroy() {
super.onDestroy();
compositeDisposable.clear(); // 或 dispose()
}
}
✅ clear() vs dispose()
clear():可继续 adddispose():不可再使用自动在生命周期结束时取消订阅
Observable.interval(1, TimeUnit.SECONDS)
.as(autoDispose(this))
.subscribe(t -> Log.d("Rx", "tick"));
或配合 AndroidLifecycleScopeProvider:
.as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this)))
✅ 优点
Observable.timer(3, TimeUnit.SECONDS)
.compose(bindToLifecycle())
.subscribe();
⚠️ 现已逐渐被 AutoDispose 替代
observable.subscribe(new Observer<String>() {
@Override
public void onNext(String s) {
textView.setText(s); // 持有 Activity
}
});
✅ 解决
CompositeDisposableAutoDisposeapi.getUser()
.subscribe(user -> updateUI(user));
✅ 正确
api.getUser()
.as(autoDispose(this))
.subscribe(user -> updateUI(user));
即使切到 Schedulers.io(),也必须取消订阅:
Observable.fromCallable(() -> doWork())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.as(autoDispose(this))
.subscribe();
✅ 强烈建议配合:
RxJava 避免内存泄漏的本质:页面销毁前,取消所有 Disposable
✅ 推荐组合:
如果你愿意,我可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。