欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2024-02-22 17:06:46
前言: 其实rxjava引起的内存泄漏是我无意中发现了,本来是想了解retrofit与rxjava相结合中是如何通过适配器模式解决的,结果却发现了rxjava是会引起内存...

前言:

其实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 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'

 根据自己的需要添加 我这里使用了如下两个

 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 结构图

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

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的内存泄漏问题,同时也给我们提了一个警告,再好的框架都有它好的一面也有坏的一面,这时做好技术选型以及规避风险就很重要了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。