前言 在Rxjava满大街跑的时代,使用过程中无法避免会有Rxjava资源回收处理不到位的地方,笔者深受其危害。当页面被销毁的时候, 未正确处理取消订阅就会导致内存泄漏,往往我们会在页面的onDestroy方法中执行如下方法:
1 2 3 if (rxDisposable!=null && !rxDisposable.isDisposed()){ rxDisposable.dispose(); }
为了代码的冗余我们还会去封装工具类去统一的处理回收,但是无法避免的会手动调用多次,那么如何更优雅及方便的进行资源的回收呢? 答案是肯定有的,本文会介绍更优雅、更安全、更方便的去使用Rxjava无需担心资源回收的问题。
使用 下面介绍两种处理资源回收的第三方库Rxlifecycle、Autodispose
1.使用Rxlifecycle 该库让Rxjava可以基于第二个生命周期去处理未完成的订阅,避免内存泄漏
Github传送门
添加依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 implementation 'com.trello.rxlifecycle2:rxlifecycle:2.2.2' implementation 'com.trello.rxlifecycle2:rxlifecycle-android:2.2.2' implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.2' implementation 'com.trello.rxlifecycle2:rxlifecycle-android-lifecycle:2.2.2' implementation 'com.trello.rxlifecycle2:rxlifecycle-kotlin:2.2.2' implementation 'com.trello.rxlifecycle2:rxlifecycle-android-lifecycle-kotlin:2.2.2'
该库提供RxAppCompatActivity、RxFragment、RxAppCompatDialogFragment、RxDialogFragment、RxFragmentActivity、RxActivity、RxDialogFragment、RxPreferenceFragment基类 方便使用者快捷使用,需要继承相应的基类就可以使用rxlifecycle管理Rxjava资源回收策略。
下面提供两种使用该库的两种使用方式: 案例都是继承与RxAppCompatActivity
1.bindToLifecycle() 在某个的生命周期发布订阅。则在对应生命周期取消订阅,如在onCreate里订阅,则在onDestroy取消订阅。在onResume里订阅,则在onStop取消订阅
案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public class RxLifecycleTestActivity extends RxAppCompatActivity { private static final String TAG = RxLifecycleTestActivity.class .getSimpleName () ; private Disposable dispose; @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_rxlifecycle_test); dispose = Observable.interval(0 , 1 , TimeUnit.MILLISECONDS) .doOnDispose(()->{ Log.e(TAG, "Unsubscribing subscription from onCreate()" ); }) .compose(this .bindToLifecycle()) .subscribe(data -> { Log.e(TAG, "onCreate: " + data.toString()); }, Throwable::printStackTrace); } @Override protected void onDestroy () { super .onDestroy(); if (dispose!=null ){ Log.e(TAG, "onDestroy: Observable订阅是否关闭:" + dispose.isDisposed()); } } } 2020 -12 -03 15 :41 :30.797 10772 -10829 /com.mi.qing.common.net E/RxLifecycleTestActivity: onCreate: 10919 2020 -12 -03 15 :41 :35.010 10772 -10829 /com.mi.qing.common.net E/RxLifecycleTestActivity: Unsubscribing subscription from onCreate () 2020-12-03 15:41:35.469 10772-10829/com.mi.qing.common.net E/RxLifecycleTestActivity: onDestroy: Observable订阅是否关闭:true
2.bindUntilEvent() 可指定生命周期取消订阅,如在onCreate里订阅,可指定在onStop里取消订阅。提供ActivityEvent类,其中的CREATE、START、 RESUME、PAUSE、STOP、 DESTROY分别对应生命周期内的方法。
案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 public class RxLifecycleTestActivity extends RxAppCompatActivity { private static final String TAG = RxLifecycleTestActivity.class .getSimpleName () ; private Disposable dispose; @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_rxlifecycle_test); dispose = Observable.interval(0 , 1 , TimeUnit.MILLISECONDS) .doOnDispose(()->{ Log.e(TAG, "Unsubscribing subscription from onCreate()" ); }) .compose(this .bindUntilEvent(ActivityEvent.STOP)) .subscribe(data -> { Log.e(TAG, "onCreate: " + data.toString()); }, Throwable::printStackTrace); } @Override protected void onPause () { super .onPause(); if (dispose!=null ){ Log.e(TAG, "onPause: Observable订阅是否关闭:" + dispose.isDisposed()); } } @Override protected void onStop () { super .onStop(); if (dispose!=null ){ Log.e(TAG, "onStop: Observable订阅是否关闭:" + dispose.isDisposed()); } } @Override protected void onDestroy () { super .onDestroy(); if (dispose!=null ){ Log.e(TAG, "onDestroy: Observable订阅是否关闭:" + dispose.isDisposed()); } } } 2020 -12 -03 15 :45 :15.035 10772 -10829 /com.mi.qing.common.net E/RxLifecycleTestActivity: onCreate: 4464 2020 -12 -03 15 :45 :15.036 10772 -10829 /com.mi.qing.common.net E/RxLifecycleTestActivity: onPause: Observable订阅是否关闭:false 2020 -12 -03 15 :45 :15.037 10772 -10829 /com.mi.qing.common.net E/RxLifecycleTestActivity: Unsubscribing subscription from onCreate () 2020-12-03 15:45:15.038 10772-10829/com.mi.qing.common.net E/RxLifecycleTestActivity: onStop: Observable订阅是否关闭:true 2020-12-03 15:45:15.039 10772-10829/com.mi.qing.common.net E/RxLifecycleTestActivity: onDestroy: Observable订阅是否关闭:true
3.不继承该库自带的基类来使用 可以在需要使用的页面创建AndroidLifecycle.createLifecycleProvider(this),得到LifecycleProvider<Lifecycle.Event>返回类型进行使用 支持bindToLifecycle、bindUntilEvent两种方式使用
案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 public class RxLifecycleTestActivity extends AppCompatActivity { private static final String TAG = RxLifecycleTestActivity.class .getSimpleName () ; private Disposable dispose; private final LifecycleProvider<Lifecycle.Event> provider = AndroidLifecycle.createLifecycleProvider(this ); @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_rxlifecycle_test); dispose = Observable.interval(0 , 1 , TimeUnit.MILLISECONDS) .doOnDispose(()->{ Log.e(TAG, "Unsubscribing subscription from onCreate()" ); }) .compose(provider.bindToLifecycle()) .subscribe(data -> { Log.e(TAG, "onCreate: " + data.toString()); }, Throwable::printStackTrace); } @Override protected void onPause () { super .onPause(); if (dispose!=null ){ Log.e(TAG, "onPause: Observable订阅是否关闭:" + dispose.isDisposed()); } } @Override protected void onStop () { super .onStop(); if (dispose!=null ){ Log.e(TAG, "onStop: Observable订阅是否关闭:" + dispose.isDisposed()); } } @Override protected void onDestroy () { super .onDestroy(); if (dispose!=null ){ Log.e(TAG, "onDestroy: Observable订阅是否关闭:" + dispose.isDisposed()); } } } 2020 -12 -03 15 :50 :35.326 10772 -10829 /com.mi.qing.common.net E/RxLifecycleTestActivity: onCreate: 6765 2020 -12 -03 15 :50 :35.327 10772 -10829 /com.mi.qing.common.net E/RxLifecycleTestActivity: onPause: Observable订阅是否关闭:false 2020 -12 -03 15 :50 :35.328 10772 -10829 /com.mi.qing.common.net E/RxLifecycleTestActivity: onStop: Observable订阅是否关闭:false 2020 -12 -03 15 :50 :35.329 10772 -10829 /com.mi.qing.common.net E/RxLifecycleTestActivity: Unsubscribing subscription from onCreate () 2020-12-03 15:50:35.330 10772-10829/com.mi.qing.common.net E/RxLifecycleTestActivity: onDestroy: Observable订阅是否关闭:true
2.使用Autodispose 该库用于自动绑定+处理RxJava流,借鉴Rxlifecycle开发,解决了Rxlifecycle的弊端,处理Rxjava流更加方便灵活。
Github传送门
添加依赖
1 2 implementation 'com.uber.autodispose:autodispose::1.4.0' implementation 'com.uber.autodispose:autodispose-android-archcomponents:1.4.0'
AutoDispose比RxLifecycle好的地方在于它不需要你的Activity或Fragment继承指定的类。只要你的Activity或Fragment的父类实现了LifecycleOwner这个接口即可。通过源码发现,support.v7包中的AppCompatActivity最终继承自SupportActivity,SupportActivity实现了LifecycleOwner接口。support.v4包中的Fragment也实现了LifecycleOwner接口。AndroidX支持库同样也实现了LifecycleOwner接口,使用时只要能够获取到LifecycleOwner的地方就可以使用AutoDispose是不是非常方便。
下面介绍它的使用方式
1.AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(LifecycleOwner owner))
在某个的生命周期发布订阅。则在对应生命周期取消订阅,如在onCreate里订阅,则在onDestroy取消订阅。在onResume里订阅,则在onStop取消订阅
案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class RxLifecycleTestActivity extends AppCompatActivity { private static final String TAG = RxLifecycleTestActivity.class .getSimpleName () ; private Disposable dispose; @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_rxlifecycle_test); dispose = Observable.interval(0 , 1 , TimeUnit.MILLISECONDS) .doOnDispose(()->{ Log.e(TAG, "Unsubscribing subscription from onCreate()" ); }) .as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this ))) .subscribe(data -> { Log.e(TAG, "onCreate: " + data.toString()); }, Throwable::printStackTrace); } }
2.AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(LifecycleOwner owner, Lifecycle.Event untilEvent)) 可指定生命周期取消订阅,如在onCreate里订阅,可指定在onStop里取消订阅。提供ActivityEvent类,其中的CREATE、START、 RESUME、PAUSE、STOP、 DESTROY分别对应生命周期内的方法。
案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class RxLifecycleTestActivity extends AppCompatActivity { private static final String TAG = RxLifecycleTestActivity.class .getSimpleName () ; private Disposable dispose; @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_rxlifecycle_test); dispose = Observable.interval(0 , 1 , TimeUnit.MILLISECONDS) .doOnDispose(()->{ Log.e(TAG, "Unsubscribing subscription from onCreate()" ); }) .as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this , Lifecycle.Event.ON_STOP))) .subscribe(data -> { Log.e(TAG, "onCreate: " + data.toString()); }, Throwable::printStackTrace); } }
总结 两种框架的使用都能解决使用rxjava流的过程内存泄漏的问题,读者们按需使用。这种方式能够大大减少开发过程中的冗余代码及处理遗漏导致的内存泄漏,读者可自行封装 简便使用。
框架及Demo源码 源码地址 MiQingWang/CommonNetFrame