Android 解决RxJava导致内存泄露的RxLifecycle

一:前景
在应用RxJava的时候,如果没有及时的解除订阅,在退出activity的时候,异步线程还在执行。对Activity的还在援用,此时就会产生内存泄露。
RxLifecycle就是为了解决rxjava导致的内存透露而产生的。
1.增加依赖

//RxLifecycle    implementation 'com.trello.rxlifecycle3:rxlifecycle:3.1.0'    implementation 'com.trello.rxlifecycle3:rxlifecycle-components:3.1.0'

2.Activity和Fragment
Activity
RxAppCompatActivity、RxActivity、RxFragmentActivity
Fragment
RxFragment、RxDialogFragment、RxPreferenceFragment、RxAppCompatDialogFragment

二:RxLifecycle应用
1.bindUntilEvent(ActivityEvent e)

public class TenActivity extends RxAppCompatActivity implements View.OnClickListener {    private Button btn;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_ten);        btn=findViewById(R.id.btn);        btn.setOnClickListener(this::onClick);    }   @Override    public void onClick(View v) {    //应用RxJava,定时每3秒打印    //compose()是惟一一个可能从数据流中失去原始Observable的操作符,所以,那些须要对整个数据流产生作用的操作(比方,subscribeOn()和observeOn())须要应用compose()来实现。相较而言,如果在flatMap()中应用subscribeOn()或者observeOn(),那么它仅仅对在flatMap()中创立的Observable起作用,而不会对剩下的流产生影响        Observable.interval(3, TimeUnit.SECONDS)                .compose(bindUntilEvent(ActivityEvent.DESTROY))//通过compose绑定RxLifecycle的Activity的生命周期                .subscribe(new Consumer<Long>() {                    @Override                    public void accept(Long aLong) throws Exception {                        Log.d("aaa", String.valueOf(aLong));                    }                });    }    @Override    protected void onDestroy() {        super.onDestroy();        Log.d("aaa", "onDestory()");    }    }        //打印后果           aaa: 0           aaa: 1           aaa: 2           aaa: 3           aaa: onDestory()

以上代码的意思是说,以后Activity执行到onDestroy时,Observable勾销订阅
bindUntilEvent前面的参数决定Observable什么时候被勾销
ActivityEvent对应的是Activity生命周期办法

public enum ActivityEvent {    CREATE,    START,    RESUME,    PAUSE,    STOP,    DESTROY;    private ActivityEvent() {    }}


2.bindToLifecycle()应用

//咱们在Activity 在onResume()生命周期里点击执行RxJava每3秒打印 Observable.interval(3, TimeUnit.SECONDS)                .compose(bindToLifecycle())//应用第二种形式bindToLifecycle绑定生命周期,没有传入去生命周期,后果是在onPause下解除绑定这是为什么呢,须要源码剖析                .subscribe(new Consumer<Long>() {                    @Override                    public void accept(Long aLong) throws Exception {                        Log.d("aaa", String.valueOf(aLong));                    }                });                     //后果:       aaa: 0       aaa: 1       aaa: 2       aaa: onPause()

源码:

 private static final Function<ActivityEvent, ActivityEvent> ACTIVITY_LIFECYCLE = new Function<ActivityEvent, ActivityEvent>() {        public ActivityEvent apply(ActivityEvent lastEvent) throws Exception {            switch(lastEvent) {            case CREATE:                return ActivityEvent.DESTROY;            case START:                return ActivityEvent.STOP;            case RESUME:                return ActivityEvent.PAUSE;            case PAUSE:                return ActivityEvent.STOP;            case STOP:                return ActivityEvent.DESTROY;            case DESTROY:                throw new OutsideLifecycleException("Cannot bind to Activity lifecycle when outside of it.");            default:                throw new UnsupportedOperationException("Binding to " + lastEvent + " not yet implemented");            }        }    };

源码意思:
如果Observable在onCreate执行,那么当执行到onDestroy时勾销订阅;
如果Observable在onStart执行,那么当执行到onStop时勾销订阅;
如果Observable在onResume执行,那么当执行到onPause时勾销订阅;
如果Observable在onPause执行,那么当执行到onStop时勾销订阅;
如果Observable在onStop执行,那么当执行到onDestroy时勾销订阅;
如果Observable在onDestroy执行,则抛出异样;
故能够解释咱们在onResume()生命周期中调用,onPause()勾销了订阅
三:组件化和Base库中应用RxLifecycle
咱们通常须要在这封装来,不会这样独自间接在Activity中应用
我依据我之前的代码封装解说一下
第一步:咱们应用RxJava中被观察者Observable,去定义compose()来绑定生命周期

//这里咱们对被观察者,即网络接口,进行分封装,compose(lifecycle.bindUntilEvent(event)),咱们应用bindUntilEvent绑定生命周期办法,故须要传递2个参数,一个是 LifecycleProvider<ActivityEvent> 去调用bindUntilEvent,一个是ActivityEvent参数 public static <T> Observable<T> getObservable(            Observable<T> apiObservable,            LifecycleProvider<ActivityEvent> lifecycle,            ActivityEvent event) {        // showLog(request);        Observable<T> observable;        if (lifecycle != null) {            // 手动治理移除监听生命周期.eg:ActivityEvent.STOP            observable =                    apiObservable                            // 须要在这个地位增加                            .compose(lifecycle.bindUntilEvent(event))                            .onErrorResumeNext(new HttpResultFunction<>())                            .subscribeOn(Schedulers.io())                            .observeOn(AndroidSchedulers.mainThread());        } else {            observable = getObservable(apiObservable);        }        return observable;    }

第二步:咱们在Model层进行网络申请,咱们以获取验证码为例
在这里咱们被观察者订阅了观察者,Rxjava实现了异步

 @Override    public void getVerfitCode(LifecycleProvider<ActivityEvent> event, SendSMSBean sendSMSBean, LoginCallBack loginCallBack) {        HttpObservable.getObservable(apiService.getSMS(sendSMSBean), event, ActivityEvent.DESTROY)//次要是来剖析这个的,之前须要的2个参数,event这个参数由他的调用者给,ActivityEvent.DESTROY生命周期,咱们给了Destroy(),这是一个枚举类型        //那么他的调用者mvp模式下,交由P层调用传入LifecycleProvider<ActivityEvent>这个参数                .subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new HttpObserver<String>() {//订阅,HttpObserver观察者                    @Override                    public void onSuccess(String response) {                        loginCallBack.getCodeSuccess(response);                    }                    @Override                    public void onFail(boolean connect, int code, String msg) {                        loginCallBack.getCodeFail(connect, code, msg);                    }                    @Override                    public void onStart(Disposable disposable) {                    }                });}

第三步:P层实现类LoginPresenter中这个办法中传递给了Mode层实现类LoginModel中参数,那么getProvider()办法获取到了LifecycleProvider<ActivityEvent>这个参数

public void getVerfitCode(String phone, String ip, int codeType) {        SendSMSBean sendSMSBean = new SendSMSBean(phone, ip, codeType);        mode.getVerfitCode(getProvider(), sendSMSBean, this);    }

第四步:交由getProvider()获取到参数,这是在我封装的BaseProvider中实现的

private LifecycleProvider<ActivityEvent> provider;    private LifecycleProvider<FragmentEvent> fragmentProvider;    public BasePresenter(LifecycleProvider<ActivityEvent> provider,ActivityEvent event){        this.provider=provider;    }    public BasePresenter(LifecycleProvider<FragmentEvent> fragmentProvider,FragmentEvent event){        this.fragmentProvider=fragmentProvider;                 }    public LifecycleProvider<ActivityEvent> getProvider(){        return provider;    }    public LifecycleProvider<FragmentEvent> getFragmentProvider(){        return fragmentProvider;    }

那么具体实现类LoginPresenter,谁实现了LoginPresenter就传递过来

    public LoginPresenter(LifecycleProvider<ActivityEvent> provider, ActivityEvent event) {        super(provider, event);//调用父类        mode = new LoginModel();    }   

第五步:在Activity中具体实现是LoginActivity中LoginActivity 继承BaseActivity ,BaseActivity继承RxAppCompatActivity

    @Override    protected LoginPresenter loadPresenter() {        return new LoginPresenter(this, ActivityEvent.DESTROY);    }    //这里传递this代表以后Activity,即LoginActivity,是继承了RxAppCompatActivity的如果想晓得为什么this,能传入参数LifecycleProvider<ActivityEvent>,那么咱们就要看RxAppCompatActivity的源码了

RxAppCompatActivity的源码

public abstract class RxAppCompatActivity extends AppCompatActivity implements LifecycleProvider<ActivityEvent> {    private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();    public RxAppCompatActivity() {    }    @ContentView    public RxAppCompatActivity(@LayoutRes int contentLayoutId) {        super(contentLayoutId);    }    @NonNull    @CheckResult    public final Observable<ActivityEvent> lifecycle() {        return this.lifecycleSubject.hide();    }    @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);    }    。。。。。。局部源码    //能够看到他实现了接口implements LifecycleProvider<ActivityEvent>    //故这个this,代表LoginActivity也实现了父类这个接口故绑定了LoginActivity的生命周期   // Java中子类会继承父类对于接口的实现。    }

END:愿以渺小启程以平凡完结