阅读 1078

Android 开发中 RxJava 生命周期简易管理


image.png

为什么要做生命周期管理

使用 RxJava 这个库做开发也已经很多年了,从刚开始使用到现在也经历了很多个阶段,中间也遇到了很多问题,今天我们就 RxJava 的生命周期问题好好聊一聊。

  • RxJava 怎么用,想必大家都是知道的:
Observable.create<String> {   
    // do something
    it.onNext("")
    it.onComplete()
}        
    .subscribeOn(Schedulers.io())      
    .observeOn(AndroidSchedulers.mainThread())      
    .subscribe({  
        // onNext
    }, {           
        // onError
    })
复制代码
  • 这样就是一个简单的异步处理,但是如果只是这样使用肯定是不行,因为在 Android 开发过程中,如果在进行耗时操作的时候,操作还没有结束,这个时候退出的当前 Activity,这个时候,这段代码的处理并不会因为 Activity 的退出而结束,就会导致内存泄漏等问题,严重的时候甚至会导致 APP 闪退。

如何管理生命周期

那么,如何对 RxJava 的生命周期进行管理呢?RxJava 给我们提供了 CompositeDisposable 这个类,用于对 RxJava 的管理。

val disposable = Observable.create<String> {   
    // do something
    it.onNext("")
    it.onComplete()
}        
    .subscribeOn(Schedulers.io())      
    .observeOn(AndroidSchedulers.mainThread())      
    .subscribe({  
        // onNext
    }, {           
        // onError
    })
val disposables = CompositeDisposable()
disposables.add(disposable)
disposables.clear()
复制代码
  • 每次使用 RxJava,都将其生成的 Disposable 对象添加到 CompositeDisposable 对象中,并在每个界面结束的时候,调用 CompositeDisposable 对象的 clear()方法取消事件。
  • 在较新版本的 RxJava 使用过程中,我们会发现,如果没有对 subscribe 方法的返回参数进行处理,studio 就会报黄色的警告,这是因为 RxJavasubscribe 方法添加了 @CheckReturnValue 注解,要求我们对其返回值进行处理。

这就是我第一阶段的处理,在每次使用到 RxJava 的时候,添加 CompositeDisposable ,并在 ActivityonDestroy 方法中进行处理。

简易管理的第一个版本

从上面的处理引申出来,无非是将相关操作封装到基类中,提供一个方法 addDisposable 来将 RxJava 请求添加到生命周期管理。 后来使用了 Google Jetpack 中的 ViewModel,就将最后的清理操作放到了 ViewModelonCleared 方法中。

  • 但是,这些处理都有一个共同的问题,那就是不够优雅。
addDisposable(
    Observable.create<String> {   
        // do something
        it.onNext("")
        it.onComplete()
    }        
        .subscribeOn(Schedulers.io())      
        .observeOn(AndroidSchedulers.mainThread())      
        .subscribe({  
            // onNext
        }, {           
            // onError
        })
)
val disposable = Observable.create<String> {   
    // do something
    it.onNext("")
    it.onComplete()
}        
    .subscribeOn(Schedulers.io())      
    .observeOn(AndroidSchedulers.mainThread())      
    .subscribe({  
        // onNext
    }, {           
        // onError
    })
addDisposable(disposable)
复制代码
  • 每次在使用 RxJava 的时候都要调用 addDisposable,一次两次没什么,但如果项目中用的多了,就会觉得很繁琐,所以,我产生对其进行优化的念头。
  • 第一个想法就是:如何让他在链式的调用的过程中,完成生命周期管理的绑定。
  • 这样的话就需要我们在 RxJava 的类中添加方法,如果是 Java 开发当然是办不到的,我们不能修改 RxJava 的源码,但是在 Kotlin 中,我们可以使用 拓展方法 来达到这一效果。
  • 首先,要对生命周期进行统一的管理,我们就需要把生命周期管理相关的方法抽取成一个接口:
interface RxLifecycleOwner {   
    /** RxJ 生命周期管理 */   
    var disposables: CompositeDisposable?   
    
    /**    
     * 将 Rx 添加到生命周期管理    
     */   
    fun addDisposable(dis: Disposable) {        
         disposables?.add(dis)   
    }   
     
     /**     
      * 处理所有添加到生命周期管理的事件    
      */   
     fun disposeAll() {      
        disposables?.clear()       
        disposables = null   
     }
}
复制代码
  • Kotlin 中接口的方法是可以有默认实现的。
  • 然后添加 扩展方法
/** 
 * 订阅并关联生命周期管理 
 * 
 * @param owner Rx 生命周期管理接口 
 * @param onNext 事件处理 
 * @param onComplete 事件完成 
 * @param onSubscribe 事件订阅 
 * 
 * @return [Disposable] 事件对象 
 */
fun <T> Observable<T>.subscribeWithOwner(owner: RxLifecycleOwner,                                        
                                                            onNext: Consumer<T> = Functions.emptyConsumer(),                                      
                                                            onError: Consumer<Throwable> = Functions.ON_ERROR_MISSING,                            
                                                            onComplete: Action = Functions.EMPTY_ACTION,                     
                                                            onSubscribe: Consumer<Disposable> = Functions.emptyConsumer()
): Disposable {    
    val disposable = this.subscribe(onNext, onError, onComplete, onSubscribe)   
    owner.addDisposable(disposable)    
    return disposable
}

/** 
 * 订阅并关联生命周期管理 
 * 
 * @param owner Rx 生命周期管理接口 
 * @param observer 观察者对象 
 */
fun <T> Observable<T>.subscribeWithOwner(owner: RxLifecycleOwner,      
                                                            observer: Observer<T>
) {    
    this.subscribe(object : Observer<T> {        
        override fun onComplete() {          
            observer.onComplete()        
        }        
        override fun onSubscribe(d: Disposable) {    
            observer.onSubscribe(d)          
            owner.addDisposable(d)     
        }       
        override fun onNext(t: T) {     
            observer.onNext(t)    
        }        
        override fun onError(e: Throwable) {     
            observer.onError(e)     
        }   
    })
}
复制代码
  • 使用时只需要实现 RxLifecycleOwner 接口,并初始化CompositeDisposable 对象就可以了。
class BaseViewModel
    : ViewModel(), RxLifeCycleOwner {
    
    /** Rx 生命周期管理 */
    override var disposables: CompositeDisposable? = CompositeDisposable()
    
    override fun onCleared() {    
         // 处理 Rx 事件    
         disposeAll()
    }
}

class MainViewModel : BaseViewModel() {

    fun doSomething() {
        Observable.create<String> {   
            // do something
            it.onNext("")
            it.onComplete()
        }        
         .subscribeOn(Schedulers.io())      
         .observeOn(AndroidSchedulers.mainThread())      
         .subscribeWithOwner(this, {  
                 // onNext
         }, {           
                // onError
         })
       }
}
复制代码
  • 这样,第一个版本就完成了,每次使用 RxJava 都无需多余的代码,生命周期管理也能链式调用。

简易管理的第二个版本

经过上面的一通操作,我们已经对 RxJava 的生命周期管理进行了一定的简化,但是还是觉得复杂怎么办,为什么每次使用都要实现 RxLifecycleOwner 接口啊,每次都要手动去取消事件,好麻烦的样子,有没有更好的解决方案? 这时,LiveData 给了我灵感。

  • 众所周知,LiveData 是有生命周期感知的,他内部有一个 LifecycleBoundObserver 类,通过实现 LifecycleEventObserver 接口实现了对 Activity、Fragment 的生命周期感知,LifecycleEventObserver 中有 onStateChanged 方法,会在Activity、Fragment 生命周期方法后回调,于是,就有了接下来的操作。
/** 
 * Rx 生命周期观察者 
 * 
 * @param lifecycleOwner Android 生命周期管理接口 
 */
class RxLifecycleObserver(lifecycleOwner: LifecycleOwner) : LifecycleEventObserver, RxLifecycleOwner {   
    override var disposables: CompositeDisposable? = null   
    
    init {       
        disposables = CompositeDisposable()       
        // 将当前观察者对象添加到 Android 生命周期管理
        lifecycleOwner.lifecycle.addObserver(this)   
    }    
    
    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {   
        if (source.lifecycle.currentState == Lifecycle.State.DESTROYED) {   
            // 生命周期走到了 onDestroy,消费所有事件
            disposeAll()         
            // 移除观察者
            source.lifecycle.removeObserver(this)       
            // 从集合中移除引用
            rxLifecycles.remove(source)    
        }  
    }
}
复制代码
  • 有些地方可能是在找不到 LifecycleOwner,但有需要生命周期管理,所以保留了 RxLifecycleOwner 接口。
/** 
 * HashMap 对象,保存 Rx、Android 生命周期管理对象 
 */
internal val rxLifecycles = hashMapOf<LifecycleOwner, RxLifecycleObserver>()

/** 
 * 根据 Android 生命周期对象获取 Rx 生命周期管理对象 
 * 
 * @param owner Android 生命周期对象 
 * 
 * @return Rx 生命周期管理对象 
 */
internal fun getObserver(owner: LifecycleOwner): RxLifecycleObserver {  
    var observer: RxLifecycleObserver?  
    if (rxLifecycles.containsKey(owner)) {       
        // 集合中已包含观察者对象
        observer = rxLifecycles[owner]     
        if (observer != null) {     
            // 且不为空,返回已有的观察者对象
            return observer       
        }   
    }   
    // 没有已存在的,新建观察者对象
    observer = RxLifecycleObserver(owner)  
    // 添加到 Map 集合以复用
    rxLifecycles[owner] = observer   
    return observer
}
复制代码
  • 使用 Map 集合保存观察者对象以复用。
/** 
 * 订阅并关联生命周期管理 
 * 
 * @param owner Android 生命周期接口 
 * @param onNext 事件处理 
 * @param onComplete 事件完成 
 * @param onSubscribe 事件订阅 
 * 
 * @return [Disposable] 事件对象 
 */
fun <T> Observable<T>.subscribeWithOwner(owner: LifecycleOwner,                                      
                                                            onNext: Consumer<T> = Functions.emptyConsumer(),                                     
                                                            onError: Consumer<Throwable> = Functions.ON_ERROR_MISSING,                                
                                                            onComplete: Action = Functions.EMPTY_ACTION,                                
                                                            onSubscribe: Consumer<Disposable> = Functions.emptyConsumer()
): Disposable {  
    val disposable = this.subscribe(onNext, onError, onComplete, onSubscribe)    
    getObserver(owner).addDisposable(disposable)   
    return disposable
}

/** 
 * 订阅并关联生命周期管理 
 * 
 * @param owner Android 生命周期接口 
 * @param observer 观察者对象 
 */
fun <T> Observable<T>.subscribeWithOwner(owner: LifecycleOwner,     
                                                            observer: Observer<T>
) {   
    this.subscribe(object : Observer<T> {     
        override fun onComplete() {    
            observer.onComplete()     
        }      
        override fun onSubscribe(d: Disposable) {      
            observer.onSubscribe(d)       
            getObserver(owner).addDisposable(d)    
        }     
        override fun onNext(t: T) {   
            observer.onNext(t)     
        }      
        override fun onError(e: Throwable) {        
            observer.onError(e)   
        } 
    })
}
复制代码
  • 这样使用起来更方便了。
class MainActivity : AppCompatActivity() {
    
    fun doSomething() {
        Observable.create<String> {   
            // do something
            it.onNext("")
            it.onComplete()
        }        
         .subscribeOn(Schedulers.io())      
         .observeOn(AndroidSchedulers.mainThread())      
         .subscribeWithOwner(this, {  
                 // onNext
         }, {           
                // onError
         })
    }
}
复制代码
  • Activity 中使用。
class BaseViewModel : ViewModel(), LifecycleEventObserver {

    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {    
        when (event) {      
            Lifecycle.Event.ON_CREATE -> onCreate(source)     
            Lifecycle.Event.ON_START -> onStart(source)      
            Lifecycle.Event.ON_RESUME -> onResume(source)     
            Lifecycle.Event.ON_PAUSE -> onPause(source)     
            Lifecycle.Event.ON_STOP -> onStop(source)      
            Lifecycle.Event.ON_DESTROY -> onDestroy(source)      
            Lifecycle.Event.ON_ANY -> {    
            }   
        }
    }
}

class MainViewModel : BaseViewModel() {

    override fun onCreate(source: LifecycleOwner) {
        Observable.create<String> {   
                // do something
                it.onNext("")
                it.onComplete()
            }        
             .subscribeOn(Schedulers.io())      
             .observeOn(AndroidSchedulers.mainThread())      
             .subscribeWithOwner(source, {  
                     // onNext
             }, {           
                    // onError
             })
    }
}
复制代码

最后

  • 好了,现在一个完整的 RxJava 的生命周期处理就完成了,一共不到 300 行代码。
  • Github 地址在这里 欢迎取用。
文章分类
Android
文章标签