LifeOwnerベースのRxJavaメモリ漏洩ソリューション

5324 ワード

コンポーネント設計の考え方:LifeOwner(Activity)LifeCycle Eventを観察することによって、Activity onDestroyのすべてのDisposableが解放される.LifeOwnerについては、Android Architecture Componentsコンポーネントの紹介を参照してください.

使用方法:


ActivityとFragmentで

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

プロジェクトのすべてのActivityAppCompatActivityから継承されています.AppCompatActivity自体がLifeOwnerです.Fragmentの場合、それ自体もLifeOwnerの対象であり、使用方法は同じである.

ビューで

RxBus
    .toObservable(SynEvent::class.java)
    .subscribe {
      ...
    }
    .disposeOnDestroy(context as AppCompatActivity)
Activityに頼るViewにとって、そのContextActivity(AppCompatActivity)であるため、ここでは直接強転した.viewcontextActivityに違いありませんか?この文章を見て理解してください.
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です.

アプリケーション

RxBus
    .toObservable(SynEvent::class.java)
    .subscribe {
      ...
    }
    .disposeOnDestroy(ProcessLifecycleOwner.get())
ProcessLifecycleOwnerAndroid Architecture Componentsのコンポーネントであり、app全体のライフサイクルを観察するために使用することができる.

disposeOnStop拡張関数


使用方法はdisposeOnDestroyと同様であり、OnStopですべてのDisposableが解放されるのとは異なる.

サポートされていません

ServiceBroadcastReceiver、およびContentProviderでの使用はサポートされていません.なぜなら、彼らは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()
    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()

    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メモリリークソリューション