您的位置:

RxLifecycle详解

一、RxLifecycle简介

RxLifecycle是为了解决RxJava下Activity/Fragment生命周期管理而诞生的一个库。

与RxJava相结合,RxLifecycle提供了生命周期感知的Observable和Flowable,在Activity/Fragment生命周期结束时自动取消订阅以避免内存泄漏。

使用RxLifecycle可以在Activity/Fragment的onStop()或onDestroy()等生命周期方法中dispose()订阅事件,减小内存泄漏的风险。

二、RxLifecycle的使用

1、添加依赖

在build.gradle文件中添加以下依赖:

``` implementation 'com.trello.rxlifecycle3:rxlifecycle:3.0.0' implementation 'com.trello.rxlifecycle3:rxlifecycle-android:3.0.0' implementation 'com.trello.rxlifecycle3:rxlifecycle-components:3.0.0' ```

2、与RxJava结合使用

使用RxLifecycle与RxJava结合使用非常容易,只需要将Observable或Flowable与LifecycleProvider绑定即可。

``` Observable.just("hello world") .compose(lifecycleProvider.bindToLifecycle()) // 绑定 .subscribe(new Consumer () { @Override public void accept(String s) throws Exception { Log.d(TAG, "accept: " + s); } }); ```

3、在Activity/Fragment中使用

在Activity/Fragment中使用RxLifecycle需要实现LifecycleProvider接口,这个接口有两个实现类:

1) FragmentLifecycleProvider

2) ActivityLifecycleProvider

``` public interface LifecycleProvider { @NonNull Observable lifecycle(); @NonNull LifecycleTransformer bindUntilEvent(@NonNull T event); @NonNull LifecycleTransformer bindToLifecycle(); } ```

在Activity或Fragment中,需要实现lifecycle()方法以及绑定生命周期的方法bindUntilEvent()和bindToLifecycle()。

4、RxLifecycle绑定方式

获取LifecycleProvider实例后,RxLifecycle支持多种绑定方式,包括:

i) bindToLifecycle()

绑定Observable或Flowable到Activity/Fragment生命周期的末尾。

使用bindToLifecycle(),当Activity/Fragment的生命周期结束时,自动取消订阅,以避免内存泄漏。

``` Observable.interval(1, TimeUnit.SECONDS) .observeOn(AndroidSchedulers.mainThread()) .compose(lifecycleProvider.bindToLifecycle()) .subscribe(new Consumer() { @Override public void accept(Object o) throws Exception { Log.d(TAG, "accept: " + o.toString()); } }); ```

ii) bindUntilEvent()

绑定Observable或Flowable,直到Activity/Fragment生命周期中的某个事件发生后结束订阅。

``` Observable.interval(1, TimeUnit.SECONDS) .observeOn(AndroidSchedulers.mainThread()) .compose(lifecycleProvider.bindUntilEvent(FragmentEvent.STOP)) .subscribe(new Consumer() { @Override public void accept(Object o) throws Exception { Log.d(TAG, "accept: " + o.toString()); } }); ```

iii) bind()

使用bind()方法,可以自定义绑定方式。

``` Observable.interval(1, TimeUnit.SECONDS) .observeOn(AndroidSchedulers.mainThread()) .compose(lifecycleProvider.bind(onEvent)) // onEvent可以是任意的Lifecycle.Event .subscribe(new Consumer() { @Override public void accept(Object o) throws Exception { Log.d(TAG, "accept: " + o.toString()); } }); ```

三、RxLifecycle的拓展用法

1、在自定义View中使用RxLifecycle

在自定义View中使用RxLifecycle同样很容易,只需要通过构造函数传递给View即可。

``` public class CustomView extends View implements LifecycleProvider { private final LifecycleRegistry lifecycleRegistry; public CustomView(Context context, AttributeSet attrs) { super(context, attrs); lifecycleRegistry = new LifecycleRegistry(this); } @NonNull @Override public Observable lifecycle() { return lifecycleRegistry.lifecycle(); } @NonNull @Override public LifecycleTransformer bindUntilEvent(@NonNull FragmentEvent event) { return RxLifecycle.bindUntilEvent(lifecycleRegistry, event); } @NonNull @Override public LifecycleTransformer bindToLifecycle() { return RxLifecycle.bind(lifecycleRegistry); } } ```

2、RxLifecycle在Presenter中的使用

在MVP架构中,通常会使用Presenter来处理业务逻辑。

可以给Presenter实现LifecycleProvider接口,使用RxLifecycle绑定。

``` public class MyPresenter implements LifecycleProvider { private LifecycleRegistry lifecycleRegistry; public void attachView(View view) { lifecycleRegistry = new LifecycleRegistry(view); } public void detachView() { lifecycleRegistry.markState(Lifecycle.State.DESTROYED); } @NonNull @Override public Observable lifecycle() { return lifecycleRegistry.lifecycle(); } @NonNull @Override public LifecycleTransformer bindUntilEvent(@NonNull FragmentEvent event) { return RxLifecycle.bindUntilEvent(lifecycleRegistry, event); } @NonNull @Override public LifecycleTransformer bindToLifecycle() { return RxLifecycle.bind(lifecycleRegistry); } } ```

3、RxLifecycle在Room中的使用

在Android中,有很多使用了Room进行本地数据库操作的应用。

Room也支持RxJava和RxLifecycle,具体使用思路与RxJava结合使用相同。

``` @Dao public interface UserDao { @Query("SELECT * FROM users") Flowable > getUsers(); @Insert void insertUser(User user); @Update void updateUser(User user); @Delete void deleteUser(User user); } public class UserRepository { private UserDao userDao; public UserRepository(Context context) { AppDatabase db = AppDatabase.getDatabase(context); userDao = db.userDao(); } public Flowable > getUsers() { return userDao.getUsers() .compose(RxLifecycle. , FragmentEvent>bindUntilEvent(lifecycleProvider, FragmentEvent.STOP)); } // ... } ```

四、RxLifecycle的优化

1、使用AutoDispose替换RxLifecycle

尽管RxLifecycle可以很好地避免界面销毁时的内存泄漏,但设计上仍然会比较繁琐,尤其是需要绑定多个事件的时候,会显得非常麻烦。

AutoDispose是一个更加简单优雅的生命周期管理库,支持RxJava 2.x和3.x,可以更莫到地处理生命周期事件以及内存泄漏问题。

相比RxLifecycle,AutoDispose可以让代码更加简洁,使生命周期管理更加优雅。

2、使用lifecycle-livedata-ktx精简代码

最近,在Google官方的Android Jetpack组件库中,新增了一个lifecycle-livedata-ktx库,使LiveData与Kotlin协程更好的结合。

这个库提供了一个LiveDataScope,可以帮我们轻松实现生命周期的管理,使得代码更加精简,避免任何内存泄漏问题。

结语

RxLifecycle是一款非常方便易用的RxJava生命周期管理库。

它简单明了,支持多种绑定方式,可以用于Activity、Fragment、自定义View、Presenter、Room等各种场景,是RxJava编程中必备的工具之一。