基于LifeOwner的RxJava内存泄漏处理方案
来源:susion哒哒     阅读:608
云上智慧
发布于 2019-08-22 02:10
查看主页

组件设计思路:

通过观察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内存泄漏处理方案

免责声明:本文为用户发表,不代表网站立场,仅供参考,不构成引导等用途。 系统环境 服务器应用
相关推荐
为了在面试官面前轻松完成手写SQL的面试题,平常多积累技巧
强大的JQuery选择器!
特别篇:阿里云的购买与数据库搭建,含网站搭建
高性能Spark作业基础:调优准则及建议
Windows下zookeeper的安装&配置&用
首页
搜索
订单
购物车
我的