Android 性能优化之利用 Rxlifecycle 解决 RxJava 内存泄漏

liuyongly 7年前
   <h3><strong>前言:</strong></h3>    <p>其实RxJava引起的内存泄漏是我无意中发现了,本来是想了解Retrofit与RxJava相结合中是如何通过适配器模式解决的,结果却发现了RxJava是会引起内存泄漏的,所有想着查找一下资料学习一下如何解决RxJava引起的内存泄漏,就查到了利用Rxlifecycle开源框架可以解决,今天周末就来学习一下如何使用Rxlifecycle。</p>    <h3><strong>引用泄漏的背景:</strong></h3>    <p>RxJava作为一种响应式编程框架,是目前编程界网红,可谓是家喻户晓,其简洁的编码风格、易用易读的链式方法调用、强大的异步支持等使得RxJava被广泛使用,它通过线程调度器更容易控制和切换线程,如果该工作线程还没执行结束就退出Activity或者Fragment,就会Activity或者Fragment无法释放引起内存泄漏。</p>    <h3><strong>什么是Rxlifecycle?</strong></h3>    <p>rxlifecycle是trello开发的用于解决RxJava引起的内存泄漏的开源框架。</p>    <h3><strong>如何使用Rxlifecycle?</strong></h3>    <p><strong>1.)在build.gradle文件中添加引用</strong></p>    <pre>  <code class="language-java">compile 'com.trello:rxlifecycle:1.0'    // If you want to bind to Android-specific lifecycles  compile 'com.trello:rxlifecycle-android:1.0'    // If you want pre-written Activities and Fragments you can subclass as providers  compile 'com.trello:rxlifecycle-components:1.0'    // If you want to use Navi for providers  compile 'com.trello:rxlifecycle-navi:1.0'    // If you want to use Kotlin syntax  compile 'com.trello:rxlifecycle-kotlin:1.0'  </code></pre>    <p>根据自己的需要添加 我这里使用了如下两个</p>    <pre>  <code class="language-java"> compile 'com.trello:rxlifecycle:1.0'   compile 'com.trello:rxlifecycle-components:1.0'  </code></pre>    <p><strong>2.)根据不同的需要Activity继承RxActivity ,Fragment继承RxFragment</strong></p>    <pre>  <code class="language-java">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);      }  }  </code></pre>    <p>目前支持的Activity/Fragment 结构图</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/d009a1d7b3d8f908db362893d3b3a9a3.png"></p>    <p><strong>3.)使用bindToLifecycle()的方式</strong></p>    <p>在子类使用Observable中的compose操作符,调用,完成Observable发布的事件和当前的组件绑定,实现生命周期同步。从而实现当前组件生命周期结束时,自动取消对Observable订阅。</p>    <pre>  <code class="language-java"> 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);                      }                  });  </code></pre>    <p><strong>4.)使用bindUntilEvent()方式</strong></p>    <p>使用ActivityEvent类,其中的CREATE、START、 RESUME、PAUSE、STOP、 DESTROY分别对应生命周期内的方法。使用bindUntilEvent指定在哪个生命周期方法调用时取消订阅。</p>    <pre>  <code class="language-java">      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);                      }                  });  </code></pre>    <p><strong>5.)自定义一个RxActivity/RxFragment</strong></p>    <p>只需要你想要的Activity实现LifecycleProvider<ActivityEvent>接口就可以了,这里贴出RxActivity的源码仿照它做下修改即可。</p>    <pre>  <code class="language-java">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();      }  }  </code></pre>    <h3><strong>总结:</strong></h3>    <p>本文总结了通过RxLifeCycle解决RxJava的内存泄漏问题,同时也给我们提了一个警告,再好的框架都有它好的一面也有坏的一面,这时做好技术选型以及规避风险就很重要了。</p>    <p> </p>    <p>来自:http://www.cnblogs.com/whoislcj/p/6054167.html</p>    <p> </p>