diff --git a/library/src/main/kotlin/com/github/terrakok/cicerone/BaseRouter.kt b/library/src/main/kotlin/com/github/terrakok/cicerone/BaseRouter.kt index e1ec642..24e5423 100644 --- a/library/src/main/kotlin/com/github/terrakok/cicerone/BaseRouter.kt +++ b/library/src/main/kotlin/com/github/terrakok/cicerone/BaseRouter.kt @@ -10,12 +10,16 @@ abstract class BaseRouter { private val resultWire = ResultWire() /** - * Sets data listener with given key. + * Sets data listener with given key + * and returns [ResultListenerHandler] for availability to dispose subscription. * * After first call listener will be removed. */ - fun setResultListener(key: String, listener: ResultListener) { - resultWire.setResultListener(key, listener) + fun setResultListener( + key: String, + listener: ResultListener + ): ResultListenerHandler { + return resultWire.setResultListener(key, listener) } /** @@ -32,6 +36,5 @@ abstract class BaseRouter { */ protected fun executeCommands(vararg commands: Command) { commandBuffer.executeCommands(commands) - resultWire.flush() } } \ No newline at end of file diff --git a/library/src/main/kotlin/com/github/terrakok/cicerone/ResultWire.kt b/library/src/main/kotlin/com/github/terrakok/cicerone/ResultWire.kt index aa10014..524096f 100644 --- a/library/src/main/kotlin/com/github/terrakok/cicerone/ResultWire.kt +++ b/library/src/main/kotlin/com/github/terrakok/cicerone/ResultWire.kt @@ -1,7 +1,5 @@ package com.github.terrakok.cicerone -import java.lang.ref.WeakReference - /** * Interface definition for a result callback. */ @@ -9,22 +7,24 @@ fun interface ResultListener { fun onResult(data: Any) } -internal class ResultWire { - private val listeners = mutableMapOf>() +/** + * Handler for manual delete subscription and avoid leak + */ +fun interface ResultListenerHandler { + fun dispose() +} - fun setResultListener(key: String, listener: ResultListener) { - listeners[key] = WeakReference(listener) - } +internal class ResultWire { + private val listeners = mutableMapOf() - fun sendResult(key: String, data: Any) { - listeners.remove(key)?.get()?.let { listener -> - listener.onResult(data) + fun setResultListener(key: String, listener: ResultListener): ResultListenerHandler { + listeners[key] = listener + return ResultListenerHandler { + listeners.remove(key) } } - fun flush() { - listeners.entries - .filter { it.value.get() == null } - .forEach { listeners.remove(it.key) } + fun sendResult(key: String, data: Any) { + listeners.remove(key)?.onResult(data) } } \ No newline at end of file diff --git a/sample/src/main/java/com/github/terrakok/cicerone/sample/mvp/animation/profile/ProfilePresenter.kt b/sample/src/main/java/com/github/terrakok/cicerone/sample/mvp/animation/profile/ProfilePresenter.kt index 1835bc0..6e16bd6 100644 --- a/sample/src/main/java/com/github/terrakok/cicerone/sample/mvp/animation/profile/ProfilePresenter.kt +++ b/sample/src/main/java/com/github/terrakok/cicerone/sample/mvp/animation/profile/ProfilePresenter.kt @@ -1,5 +1,6 @@ package com.github.terrakok.cicerone.sample.mvp.animation.profile +import com.github.terrakok.cicerone.ResultListenerHandler import com.github.terrakok.cicerone.Router import com.github.terrakok.cicerone.sample.R import com.github.terrakok.cicerone.sample.Screens.SelectPhoto @@ -13,6 +14,7 @@ import moxy.MvpPresenter class ProfilePresenter( private val router: Router ) : MvpPresenter() { + private var resultListenerHandler: ResultListenerHandler? = null companion object { private const val RESULT_KEY = "photo_result" @@ -25,12 +27,17 @@ class ProfilePresenter( } fun onPhotoClicked() { - router.setResultListener(RESULT_KEY) { data -> + resultListenerHandler = router.setResultListener(RESULT_KEY) { data -> viewState!!.showPhoto(data as Int) } router.navigateTo(SelectPhoto(RESULT_KEY)) } + override fun onDestroy() { + resultListenerHandler?.dispose() + super.onDestroy() + } + fun onBackPressed() { router.exit() }