时间:2021-05-20
前言:
其实RxJava引起的内存泄漏是我无意中发现了,本来是想了解Retrofit与RxJava相结合中是如何通过适配器模式解决的,结果却发现了RxJava是会引起内存泄漏的,所有想着查找一下资料学习一下如何解决RxJava引起的内存泄漏,就查到了利用Rxlifecycle开源框架可以解决,今天周末就来学习一下如何使用Rxlifecycle。
引用泄漏的背景:
RxJava作为一种响应式编程框架,是目前编程界网红,可谓是家喻户晓,其简洁的编码风格、易用易读的链式方法调用、强大的异步支持等使得RxJava被广泛使用,它通过线程调度器更容易控制和切换线程,如果该工作线程还没执行结束就退出Activity或者Fragment,就会Activity或者Fragment无法释放引起内存泄漏。
什么是Rxlifecycle?
rxlifecycle是trello开发的用于解决RxJava引起的内存泄漏的开源框架。
github地址:https://github.com/trello/RxLifecycle
如何使用Rxlifecycle?
1.)在build.gradle文件中添加引用
compile 'com.trello:rxlifecycle:1.0'// If you want to bind to Android-specific lifecyclescompile 'com.trello:rxlifecycle-android:1.0'// If you want pre-written Activities and Fragments you can subclass as providerscompile 'com.trello:rxlifecycle-components:1.0'// If you want to use Navi for providerscompile 'com.trello:rxlifecycle-navi:1.0'// If you want to use Kotlin syntaxcompile 'com.trello:rxlifecycle-kotlin:1.0'根据自己的需要添加 我这里使用了如下两个
compile 'com.trello:rxlifecycle:1.0' compile 'com.trello:rxlifecycle-components:1.0'2.)根据不同的需要Activity继承RxActivity ,Fragment继承RxFragment
public class MainActivity7 extends RxActivity { private TextView mTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.text); //模拟内存泄露 testRxJava(); finish(); } private void testRxJava() { Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { int i = 0; while (i < 1000000000) { i++; } subscriber.onNext(String.valueOf(i)); subscriber.onCompleted(); } }).compose(this.<String>bindUntilEvent(ActivityEvent.PAUSE)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<String>() { @Override public void call(String s) { mTextView.setText(s); } }); } @Override protected void onDestroy() { super.onDestroy(); LApplication.getRefWatcher().watch(this); }}目前支持的Activity/Fragment 结构图
3.)使用bindToLifecycle()的方式
在子类使用Observable中的compose操作符,调用,完成Observable发布的事件和当前的组件绑定,实现生命周期同步。从而实现当前组件生命周期结束时,自动取消对Observable订阅。
Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { int i = 0; while (i < 1000000000) { i++; } subscriber.onNext(String.valueOf(i)); subscriber.onCompleted(); } }).compose(this.<String>bindToLifecycle()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<String>() { @Override public void call(String s) { mTextView.setText(s); } });4.)使用bindUntilEvent()方式
使用ActivityEvent类,其中的CREATE、START、 RESUME、PAUSE、STOP、 DESTROY分别对应生命周期内的方法。使用bindUntilEvent指定在哪个生命周期方法调用时取消订阅。
Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { int i = 0; while (i < 1000000000) { i++; } subscriber.onNext(String.valueOf(i)); subscriber.onCompleted(); } }).compose(this.<String>bindUntilEvent(ActivityEvent.PAUSE)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<String>() { @Override public void call(String s) { mTextView.setText(s); } });5.)自定义一个RxActivity/RxFragment
只需要你想要的Activity实现LifecycleProvider<ActivityEvent>接口就可以了,这里贴出RxActivity的源码仿照它做下修改即可。
public abstract class RxActivity extends Activity implements LifecycleProvider<ActivityEvent> { private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create(); public RxActivity() { } @NonNull @CheckResult public final Observable<ActivityEvent> lifecycle() { return this.lifecycleSubject.asObservable(); } @NonNull @CheckResult public final <T> LifecycleTransformer<T> bindUntilEvent(@NonNull ActivityEvent event) { return RxLifecycle.bindUntilEvent(this.lifecycleSubject, event); } @NonNull @CheckResult public final <T> LifecycleTransformer<T> bindToLifecycle() { return RxLifecycleAndroid.bindActivity(this.lifecycleSubject); } @CallSuper protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.lifecycleSubject.onNext(ActivityEvent.CREATE); } @CallSuper protected void onStart() { super.onStart(); this.lifecycleSubject.onNext(ActivityEvent.START); } @CallSuper protected void onResume() { super.onResume(); this.lifecycleSubject.onNext(ActivityEvent.RESUME); } @CallSuper protected void onPause() { this.lifecycleSubject.onNext(ActivityEvent.PAUSE); super.onPause(); } @CallSuper protected void onStop() { this.lifecycleSubject.onNext(ActivityEvent.STOP); super.onStop(); } @CallSuper protected void onDestroy() { this.lifecycleSubject.onNext(ActivityEvent.DESTROY); super.onDestroy(); }}总结:
本文总结了通过RxLifeCycle解决RxJava的内存泄漏问题,同时也给我们提了一个警告,再好的框架都有它好的一面也有坏的一面,这时做好技术选型以及规避风险就很重要了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
关联篇:深入Android的消息机制源码详解-Handler,MessageQueue与Looper关系关联篇:Handler内存泄漏及其解决方
一、概述在Android内存泄漏终极解决篇(上)中我们介绍了如何检查一个App是否存在内存泄漏的问题,本篇将总结典型的内存泄漏的代码,并给出对应的解决方案。内存
Android中android.view.WindowLeaked的解决办法按字面了解,WindowLeaked大概就是说一个窗体泄漏了,也就是我们常说的内存泄
字体池的应用,主要是为了解决字体不断创建导致句柄泄漏/内存泄漏的问题,这个问题在Android上也同样存在。经测试,C#WinForm原生控件不存在字体问题,但
内存溢出和内存泄漏的详解及区别内存溢出outofmemory,是指程序在申请内存时,没有足够的内存空间供其使用,出现outofmemory;比如申请了一个int