Android RxLifecycle使用详解

本文介绍RxLifecycle在Android开发中的应用,通过绑定组件生命周期自动取消RxJava订阅,有效避免内存泄漏问题。文中提供了多种集成方式及示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

github官网

RxLifecycle依赖

  • 注意:本文使用的版本是3.1版本
implementation 'com.trello.rxlifecycle3:rxlifecycle:3.1.0'

// If you want to bind to Android-specific lifecycles
implementation 'com.trello.rxlifecycle3:rxlifecycle-android:3.1.0'

// If you want pre-written Activities and Fragments you can subclass as providers
implementation 'com.trello.rxlifecycle3:rxlifecycle-components:3.1.0'

// If you want pre-written support preference Fragments you can subclass as providers
implementation 'com.trello.rxlifecycle3:rxlifecycle-components-preference:3.1.0'

// If you want to use Android Lifecycle for providers
implementation 'com.trello.rxlifecycle3:rxlifecycle-android-lifecycle:3.1.0'

// If you want to use Kotlin syntax
implementation 'com.trello.rxlifecycle3:rxlifecycle-kotlin:3.1.0'

// If you want to use Kotlin syntax with Android Lifecycle
implementation 'com.trello.rxlifecycle3:rxlifecycle-android-lifecycle-kotlin:3.1.0'

// If you want to use Navi for providers
// DEPRECATED: Use rxlifecycle-android-lifecycle instead. This will be removed in a future release.
implementation 'com.trello.rxlifecycle3:rxlifecycle-navi:3.1.0'

RxLifecycle介绍

RxLifecycle目的:解决RxJava使用中的内存泄漏问题。

RxLifecycle核心思想:通过监听Activity、Fragment的生命周期,来自动断开订阅防止内存泄漏。

例如,当使用RxJava订阅并执行耗时任务后,当Activity被finish时,如果耗时任务还未完成,没有及时取消订阅,就会导致Activity无法被回收,从而引发内存泄漏。

为了解决这个问题,就产生了RxLifecycle,让RxJava变得有生命周期感知,使得其能及时取消订阅,避免出现内存泄漏问题。

它可以让Observable发布的事件和当前的组件绑定,实现生命周期同步。
从而实现当前组件生命周期结束时,自动取消对Observable订阅。

目前网上对RxJava的内存泄漏有几种方案

  1. 手动为RxJava的每一次订阅进行控制,指定在哪个生命周期方法调用时取消订阅;
  2. 当前组件生命周期结束时,自动取消对Observable订阅

上述两种方式我都使用过,RxLifecycle显然对于第一种方式,更简单直接,并且能够在Activity/Fragment容器的指定生命周期取消订阅,实在是好用。

RxJava的内存泄漏案例

每隔1秒打印,无限循环:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.e("xyh", "onCreate: ");
        Observable.interval(2, 1, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()) // interval 默认在新线程,所以需要切换回主线程
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        Log.e("xyh", +aLong + "");
                    }
                });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e("xyh", "onDestroy: ");
    }
}

打印结果

2020-03-11 22:10:09.004 15261-15261/com.xyh.rxlifecycle E/xyh: onCreate: 
2020-03-11 22:10:11.029 15261-15261/com.xyh.rxlifecycle E/xyh: 0
2020-03-11 22:10:12.029 15261-15261/com.xyh.rxlifecycle E/xyh: 1
2020-03-11 22:10:13.029 15261-15261/com.xyh.rxlifecycle E/xyh: 2
2020-03-11 22:10:14.028 15261-15261/com.xyh.rxlifecycle E/xyh: 3
2020-03-11 22:10:15.050 15261-15261/com.xyh.rxlifecycle E/xyh: onDestroy: 
2020-03-11 22:10:15.061 15261-15261/com.xyh.rxlifecycle E/xyh: 4
2020-03-11 22:10:16.029 15261-15261/com.xyh.rxlifecycle E/xyh: 5
2020-03-11 22:10:17.028 15261-15261/com.xyh.rxlifecycle E/xyh: 6

我们发现执行onDestroy()方法后,还会继续执行,因为没有及时解除订阅,在退出activity的时候,异步线程还在执行,对activity还存在引用,此时就会产生内存泄漏。

RxLifecycle的使用

添加依赖

 //处理rxjava内存泄漏   
implementation 'com.trello.rxlifecycle3:rxlifecycle:3.1.0'
implementation 'com.trello.rxlifecycle3:rxlifecycle-android:3.1.0'
implementation 'com.trello.rxlifecycle3:rxlifecycle-components:3.1.0'

Activity/Fragment需继承RxAppCompatActivity/RxFragment,目前支持的有如下:
在这里插入图片描述

1. 继承RxAppCompatActivity :

Activity需要继承RxAppCompatActivity,Fragment需要继承RxFragment。

public class MainActivity extends RxAppCompatActivity {
      ...
      ...
}

在项目中针对base类的容器中继承实现对应的Rx类即可

public abstract class BaseActivity extends RxAppCompatActivity {

}

2. 使用compose操作符绑定容器生命周期

有两种方式:

方式1:使用bindToLifecycle()

以Activity为例,在Activity中使用bindToLifecycle()方法,完成Observable发布的事件和当前的组件绑定,实现生命周期同步。从而实现当前组件生命周期结束时,自动取消对Observable订阅,代码如下:

在onResume()进行绑定订阅,则在onPause()进行解除订阅,生命周期是两两对应的。

public class MainActivity extends RxAppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Log.e("xyh", "onCreate: ");

        //在某个生命周期进行绑定,在对应的生命周期进行订阅解除,当执行onDestory()时, 自动解除订阅
        Observable.interval(3, 2, TimeUnit.SECONDS)
                .doOnDispose(new Action() {
                    @Override
                    public void run() throws Exception {
                        Log.e("xyh", "解除了订阅");
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .compose(this.<Long>bindToLifecycle())
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        //在onCreate()中启动,一直运行到onDestory()
                        Log.e("xyh", +aLong + "");
                    }
                });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e("xyh", "onDestroy: ");
    }
}

方式2:使用bindUntilEvent()

使用ActivityEvent类,其中的CREATE、START、 RESUME、PAUSE、STOP、 DESTROY分别对应生命周期内的方法。使用bindUntilEvent指定在哪个生命周期方法调用时取消订阅:

public class MainActivity extends RxAppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Log.e("xyh", "onCreate: ");

        Observable.interval(3, 2, TimeUnit.SECONDS)
                .doOnDispose(new Action() {
                    @Override
                    public void run() throws Exception {
                        Log.e("xyh", "解除了订阅");
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
         
                .compose(this.<Long>bindUntilEvent(ActivityEvent.DESTROY)) // 手动指定在生命周期onDestory()时,取消订阅。
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        //在onCreate()中启动,一直运行到onDestory()
                        Log.e("xyh", +aLong + "");
                    }
                });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e("xyh", "onDestroy: ");
    }
}

打印结果:

我们发现执行,在退出activity的时候,解除了订阅,不再继续执行,解决类内存泄漏。

04-03 17:10:38.296 29186-29186/? E/xyh: onCreate: 
04-03 17:10:41.311 29186-29219/com.xiaoyehai.rxlifecycle E/xyh: 0
04-03 17:10:43.310 29186-29219/com.xiaoyehai.rxlifecycle E/xyh: 1
04-03 17:10:45.311 29186-29219/com.xiaoyehai.rxlifecycle E/xyh: 2
04-03 17:10:46.723 29186-29186/com.xiaoyehai.rxlifecycle E/xyh: 解除了订阅
04-03 17:10:46.724 29186-29186/com.xiaoyehai.rxlifecycle E/xyh: onDestroy: 

以Activity为例,主要有如下两种方法:

bindToLifecycle()  //在某个生命周期进行绑定,在对应的生命周期进行订阅解除。
//在onResume()进行绑定订阅,则在onPause()进行解除订阅,生命周期是两两对应的。

bindUntilEvent(@NonNull ActivityEvent event)  //该方法指定在哪个生命周期方法调用时取消订阅。

Fragment也有同样的两种方法,只是方法名会有所不同。

其中ActivityEvent是一个枚举类,对应于Activity的生命周期:

public enum ActivityEvent {

    CREATE,
    START,
    RESUME,
    PAUSE,
    STOP,
    DESTROY

}

不需要继承RxAppCompatActivity/RxFragment实现

上面的方式需要继承RxAppCompatActivity,如果我们自己有BaseActivity,所以不能继承RxActvivty,RxAppCompatActivity、RxFragment,NaviActivity。

为了保持代码的灵活性,我们只需要添加下面的依赖即可:

// 使用Android生命周期作为提供者
 implementation 'com.trello.rxlifecycle3:rxlifecycle-android-lifecycle:3.1.0'

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.e("xyh", "onCreate: ");

        LifecycleProvider<Lifecycle.Event> provider = AndroidLifecycle.createLifecycleProvider(this);
        Observable.interval(3, 2, TimeUnit.SECONDS)
                .doOnDispose(new Action() {
                    @Override
                    public void run() throws Exception {
                        Log.e("xyh", "解除了订阅");
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .compose(provider.<Long>bindToLifecycle())
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        //在onCreate()中启动,一直运行到onDestory()
                        Log.e("xyh", +aLong + "");
                    }
                });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e("xyh", "onDestroy: ");
    }
}

2020-03-11 22:19:29.329 16751-16751/com.xyh.rxlifecycle E/xyh: 0
2020-03-11 22:19:31.327 16751-16751/com.xyh.rxlifecycle E/xyh: 1
2020-03-11 22:19:33.108 16751-16751/com.xyh.rxlifecycle E/xyh: 解除了订阅
2020-03-11 22:19:33.111 16751-16751/com.xyh.rxlifecycle E/xyh: onDestroy: 

把LifecycleProvider抽取到BaseActivity中

public abstract class BaseActivity extends AppCompatActivity {

    protected LifecycleProvider<Lifecycle.Event> mLifecycleProvider;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(getLayoutId());

        mLifecycleProvider = AndroidLifecycle.createLifecycleProvider(this);

        init();
    }

    protected abstract int getLayoutId();

    protected abstract void init();
}
public class MainActivity extends BaseActivity {

    @Override
    protected int getLayoutId() {
        return R.layout.activity_main;
    }

    @Override
    protected void init() {
        Log.e("xyh", "init: ");
        Observable.interval(2, 1, TimeUnit.SECONDS)
                .doOnDispose(new Action() {
                    @Override
                    public void run() throws Exception {
                        Log.e("xyh", "解除了订阅");
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .compose(mLifecycleProvider.<Long>bindToLifecycle())
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        //在onCreate()中启动,一直运行到onDestory()
                        Log.e("xyh", +aLong + "");
                    }
                });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e("xyh", "onDestroy: ");
    }
}

这里我们要用到LifecycleProvide这个接口。值得一提的是这个接口已经在RxAppCompatActivity中实现了,所以为什么可以继承RxAppCompatActivity,赋予接口引用就可以使用它了。

MVP中使用RxLifecycle

这只是一个很简单的mvp案例,主要是演示RxLifecycle在mvp中的使用,在项目实际开发中可以进行封装。

不需要继承RxAppCompatActivity/RxFragment方式

public class MainActivity extends BaseActivity implements MainView {

    @Override
    protected int getLayoutId() {
        return R.layout.activity_main;
    }

    @Override
    protected void init() {
        Log.e("xyh", "init: ");
        MainPresenter mainPresenter = new MainPresenter(mLifecycleProvider, this);
        mainPresenter.loadData();
    }

    @Override
    public void onSuccess(String s) {
        Log.e("xyh", "onSuccess: " + s);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e("xyh", "onDestroy: ");
    }
}

public class MainModel {

    public Observable<Long> loadData() {

        Observable<Long> observable =
                Observable
                        .interval(2, 1, TimeUnit.SECONDS)
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread());

        return observable;
    }
}
public class MainPresenter {

    public LifecycleProvider<Lifecycle.Event> lifecycleProvider;
    public MainView mainView;
    private final MainModel mMainModel;

    public MainPresenter(LifecycleProvider<Lifecycle.Event> lifecycleProvider, MainView mainView) {
        this.lifecycleProvider = lifecycleProvider;
        this.mainView = mainView;
        mMainModel = new MainModel();
    }

    public void loadData() {
        mMainModel.loadData()
                .doOnDispose(new Action() {
                    @Override
                    public void run() throws Exception {
                        Log.e("xyh", "解除了订阅");
                    }
                })
                .compose(lifecycleProvider.<Long>bindToLifecycle())
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Long aLong) {
                        mainView.onSuccess(aLong + "");
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });


    }
}

使用继承RxAppCompatActivity/RxFragment方式

MainPresenter mainPresenter = new MainPresenter(bindToLifecycle(), this);
mainPresenter.loadData();
public class MainPresenter {

    public LifecycleTransformer lifecycleTransformer;
    public MainView mainView;
    private final MainModel mMainModel;

    public MainPresenter(LifecycleTransformer lifecycleTransformer, MainView mainView) {
        this.lifecycleTransformer = lifecycleTransformer;
        this.mainView = mainView;
        mMainModel = new MainModel();
    }

    public void loadData() {
        mMainModel.loadData()
                .doOnDispose(new Action() {
                    @Override
                    public void run() throws Exception {
                        Log.e("xyh", "解除了订阅");
                    }
                })
                .compose(lifecycleTransformer)
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Long aLong) {
                        mainView.onSuccess(aLong + "");
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }
}

Fragment中使用RxLifecycle

Fragment中使用和在Activity中的使用基本一致。

public abstract class BaseFragment extends Fragment {

    protected LifecycleProvider<Lifecycle.Event> mLifecycleProvider;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=inflater.inflate(getLayoutId(),container,false);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mLifecycleProvider = AndroidLifecycle.createLifecycleProvider(this);
		 //要用this,he fragment的生命周期绑定在一起如果使用getActivity()的话就是和Activity的生命周期绑定在一起
        //mLifecycleProvider = AndroidLifecycle.createLifecycleProvider(getActivity());


        init();

    }

    protected abstract int getLayoutId();

    protected abstract void init();


}

public class HomeFrgament extends BaseFragment {
    @Override
    protected int getLayoutId() {
        return R.layout.fragment_home;
    }

    @Override
    protected void init() {

        Log.e("xyh", "init: ");
        Observable.interval(2, 1, TimeUnit.SECONDS)
                .doOnDispose(new Action() {
                    @Override
                    public void run() throws Exception {
                        Log.e("xyh", "解除了订阅");
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .compose(mLifecycleProvider.<Long>bindToLifecycle())
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        //在onCreate()中启动,一直运行到onDestory()
                        Log.e("xyh", +aLong + "");
                    }
                });
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.e("xyh", "HomeFrgament==onDestroyView: " );
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e("xyh", "HomeFrgament==onDestroy: " );
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值