美文网首页Android技术知识Android知识Android开发
基于LifeOwner的RxJava内存泄漏解决方案

基于LifeOwner的RxJava内存泄漏解决方案

作者: susion哒哒 | 来源:发表于2019-07-29 16:38 被阅读7次

    组件设计思路:

    通过观察LifeOwner(Activity)LifeCycle Event,在ActivityonDestroy时释放掉其所有的Disposable

    了解LifeOwner可以看一下这篇文章: Android Architecture Components 组件介绍

    使用方法:

    在Activity与Fragment中

    RxBus
        .toObservable(SynEvent::class.java)
        .subscribe {
          ...
        }
        .disposeOnDestroy(this)
    

    项目中所有的Activity都是继承自AppCompatActivityAppCompatActivity本身就是一个LifeOwner

    对于Fragment,其本身也是LifeOwner对象,使用方式同上。

    在View中

    RxBus
        .toObservable(SynEvent::class.java)
        .subscribe {
          ...
        }
        .disposeOnDestroy(context as AppCompatActivity)
    

    对于依托于ActivityView来说,其Context就是Activity(AppCompatActivity),所以这里直接做了强转。

    viewcontext一定是Activity吗? 可以看这篇文章了解一下:

    View.getContext()一定会返回 Activity 对象么?

    即在5.0以上的系统上返回的就是Avctivity,即LifeOwner,所以对于这个强转还是需要注意的。

    PS: 目前我们的项目minSdkVersion21。如果不是的话不能这样使用。

    在Presenter中

    RxBus
        .toObservable(SynEvent::class.java)
        .subscribe {
          ...
        }
        .disposeOnDestroy(view.lifeContext())
    

    由于我们项目中所有MVP中的View都继承自下面接口:

    interface BaseLifeCycleView {
        fun lifeContext(): AppCompatActivity
    }
    

    所以上面view.lifeContext()就是LifeOwner

    在Application中

    RxBus
        .toObservable(SynEvent::class.java)
        .subscribe {
          ...
        }
        .disposeOnDestroy(ProcessLifecycleOwner.get())
    

    ProcessLifecycleOwner也是Android Architecture Components中的组件,它可以用来观察整个app的生命周期。

    disposeOnStop 扩展函数

    使用方式与disposeOnDestroy相同,不同的是会在OnStop时释放掉所有的Disposable

    不支持

    不支持在ServiceBroadcastReceiverContentProvider中使用,因为他们并不是LifeOwner。不过可以简单继承一下,然后自己改造成LifeOwner

    实现原理

    实现原理很简单:

    一个LifeOwner对象创建一个LifeObserver,它持有着LifeOwner的所有Disposable。在LifeOwner的Lifecycle.Event.ON_DESTROY时,释放LifeOwner的所有Disposable

    主要有2个组件:

    DestroyLifeCycleObserver

    它是一个LifecycleObserver,持有LifecycleOwner并负责其所有的Disposable的释放工作。

    internal class DestroyLifeCycleObserver(val lifeOwner: LifecycleOwner) : LifecycleObserver {
    
        private val disposableList = ArrayList<Disposable>()
        var requestRemoveLifecycleObserver: RequestRemoveLifecycleObserver? = null
    
        init {
            lifeOwner.lifecycle.addObserver(this)
        }
    
        @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
        fun onDestroy() {
            LogUtils.d(TAG, "${getKey()} OnLifecycleEvent ON_DESTROY , disposableList.size : ${disposableList.size}")
            disposableList.forEach {
                if (!it.isDisposed) {
                    it.dispose()
                }
            }
            requestRemoveLifecycleObserver?.requestRemoveDestroyObserver(this)
        }
    
        fun addDisposable(disposable: Disposable) {
            if (disposable.isDisposed) return
            disposableList.add(disposable)
        }
    
        fun getKey() = lifeOwner.toString()
    }
    

    GlobalRxDisposeManager

    主要负责维护所有的LifeCycleObserver, 以DestroyLifeCycleObserver为例:

    object GlobalRxDisposeManager {
    
        private val rxLifecycleObservers = HashMap<String, DestroyLifeCycleObserver?>()
    
        fun getLifecycleObserver(key: String): DestroyLifeCycleObserver? {
            return rxLifecycleObservers[key]
        }
    
        fun addLifecycleObserver(lifeCycleObserver: DestroyLifeCycleObserver) {
            rxLifecycleObservers[lifeCycleObserver.getKey()] = lifeCycleObserver
            lifeCycleObserver.requestRemoveLifecycleObserver = object : RequestRemoveLifecycleObserver {
                override fun requestRemoveDestroyObserver(observer: DestroyLifeCycleObserver) {
                    destroyLifeCycleObserver.remove(observer.getKey())
                    LogUtils.d(TAG, "destroyLifeCycleObserver size : ${destroyLifeCycleObserver.size}")
                }
                ...
            }
        }
        
        ...
    }
    

    disposeOnDestroy扩展函数

    组合GlobalRxDisposeManagerDestroyLifeCycleObserver并简化使用:

    fun Disposable.disposeOnDestroy(lifeOwner: LifecycleOwner): Disposable {
        LogUtils.d(TAG, "life owner key : ${lifeOwner}")
        var lifecycleObserver = GlobalRxDisposeManager.getDestroyObserver(lifeOwner.toString())
    
        if (lifecycleObserver == null) {
            lifecycleObserver = DestroyLifeCycleObserver(lifeOwner)
            GlobalRxDisposeManager.addDestroyObserver(lifecycleObserver)
        }
    
        lifecycleObserver.addDisposable(this)
    
        return this
    }
    

    源码 : RxLifeCycleExtensions

    原文链接 : Android进阶-基于LifeOwner的RxJava内存泄漏解决方案

    相关文章

      网友评论

        本文标题:基于LifeOwner的RxJava内存泄漏解决方案

        本文链接:https://www.haomeiwen.com/subject/mlzbrctx.html