LifeOwnerベースのRxJavaメモリ漏洩ソリューション
5324 ワード
コンポーネント設計の考え方:
使用方法:
LifeOwner(Activity)
のLifeCycle Event
を観察することによって、Activity onDestroy
のすべてのDisposable
が解放される.LifeOwner
については、Android Architecture Componentsコンポーネントの紹介を参照してください.使用方法:
ActivityとFragmentで
RxBus
.toObservable(SynEvent::class.java)
.subscribe {
...
}
.disposeOnDestroy(this)
プロジェクトのすべてのActivity
はAppCompatActivity
から継承されています.AppCompatActivity
自体がLifeOwner
です.Fragment
の場合、それ自体もLifeOwner
の対象であり、使用方法は同じである.
ビューで
RxBus
.toObservable(SynEvent::class.java)
.subscribe {
...
}
.disposeOnDestroy(context as AppCompatActivity)
Activity
に頼るView
にとって、そのContext
はActivity(AppCompatActivity)
であるため、ここでは直接強転した.view
のcontext
はActivity
に違いありませんか?この文章を見て理解してください.
View.getContext()は必ずActivityオブジェクトを返しますか?
つまり5.0以上のシステムで戻ってくるのがAvctivity
、つまりLifeOwner
なので、この強転には注意が必要です.
PS:現在、私たちのプロジェクトminSdkVersion
は21
です.そうでなければこのように使うことはできません.
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())
ProcessLifecycleOwner
もAndroid Architecture Components
のコンポーネントであり、app全体のライフサイクルを観察するために使用することができる.
disposeOnStop拡張関数
使用方法はdisposeOnDestroy
と同様であり、OnStop
ですべてのDisposable
が解放されるのとは異なる.
サポートされていません Service
、BroadcastReceiver
、および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拡張関数
GlobalRxDisposeManager
とDestroyLifeCycleObserver
を組み合わせて使用を簡単にします.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メモリリークソリューション
RxBus
.toObservable(SynEvent::class.java)
.subscribe {
...
}
.disposeOnDestroy(this)
RxBus
.toObservable(SynEvent::class.java)
.subscribe {
...
}
.disposeOnDestroy(context as AppCompatActivity)
RxBus
.toObservable(SynEvent::class.java)
.subscribe {
...
}
.disposeOnDestroy(view.lifeContext())
interface BaseLifeCycleView {
fun lifeContext(): AppCompatActivity
}
RxBus
.toObservable(SynEvent::class.java)
.subscribe {
...
}
.disposeOnDestroy(ProcessLifecycleOwner.get())
Service
、BroadcastReceiver
、および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拡張関数
GlobalRxDisposeManager
とDestroyLifeCycleObserver
を組み合わせて使用を簡単にします.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メモリリークソリューション
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()
}
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}")
}
...
}
}
...
}
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
}