From 1039b98a5129dd4792c2e7cbebdaef1061fe42ea Mon Sep 17 00:00:00 2001 From: Jay Ohms Date: Mon, 5 Jun 2023 12:57:54 -0400 Subject: [PATCH 1/2] Fix delegate lifecycle issues by calling onStop() when the destination becomes inactive and checking the lifecycle state before handling incoming bridge messages --- .../dev/hotwire/strada/BridgeDelegate.kt | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/strada/src/main/kotlin/dev/hotwire/strada/BridgeDelegate.kt b/strada/src/main/kotlin/dev/hotwire/strada/BridgeDelegate.kt index b275b49..37299e0 100644 --- a/strada/src/main/kotlin/dev/hotwire/strada/BridgeDelegate.kt +++ b/strada/src/main/kotlin/dev/hotwire/strada/BridgeDelegate.kt @@ -2,6 +2,7 @@ package dev.hotwire.strada import android.webkit.WebView import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner @Suppress("unused") @@ -10,12 +11,16 @@ class BridgeDelegate( private val componentFactories: List>> ) { internal var bridge: Bridge? = null - private var destinationIsActive = true - private val components = hashMapOf>() + private val initializedComponents = hashMapOf>() + private val lifecycle get() = destination.bridgeDestinationLifecycleOwner().lifecycle + private val destinationIsActive get() = lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED) + + private val allComponents: List> + get() = initializedComponents.map { it.value } val activeComponents: List> get() = when (destinationIsActive) { - true -> components.map { it.value } + true -> allComponents else -> emptyList() } @@ -55,7 +60,7 @@ class BridgeDelegate( } internal fun bridgeDidReceiveMessage(message: Message): Boolean { - return if (destination.bridgeDestinationLocation() == message.metadata?.url) { + return if (destinationIsActive && destination.bridgeDestinationLocation() == message.metadata?.url) { logMessage("bridgeDidReceiveMessage", message) getOrCreateComponent(message.component)?.handle(message) true @@ -80,13 +85,11 @@ class BridgeDelegate( } private fun onStart() { - destinationIsActive = true activeComponents.forEach { it.onStart() } } private fun onStop() { - destinationIsActive = false - activeComponents.forEach { it.onStop() } + allComponents.forEach { it.onStop() } } // Retrieve component(s) by type @@ -101,6 +104,6 @@ class BridgeDelegate( private fun getOrCreateComponent(name: String): BridgeComponent? { val factory = componentFactories.firstOrNull { it.name == name } ?: return null - return components.getOrPut(name) { factory.create(this) } + return initializedComponents.getOrPut(name) { factory.create(this) } } } From 62abee81e928949197e4ef89bbee8a2c7b4e4abe Mon Sep 17 00:00:00 2001 From: Jay Ohms Date: Mon, 5 Jun 2023 13:48:48 -0400 Subject: [PATCH 2/2] Simplify activeComponents logic --- strada/src/main/kotlin/dev/hotwire/strada/BridgeDelegate.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/strada/src/main/kotlin/dev/hotwire/strada/BridgeDelegate.kt b/strada/src/main/kotlin/dev/hotwire/strada/BridgeDelegate.kt index 37299e0..9f8c970 100644 --- a/strada/src/main/kotlin/dev/hotwire/strada/BridgeDelegate.kt +++ b/strada/src/main/kotlin/dev/hotwire/strada/BridgeDelegate.kt @@ -19,10 +19,7 @@ class BridgeDelegate( get() = initializedComponents.map { it.value } val activeComponents: List> - get() = when (destinationIsActive) { - true -> allComponents - else -> emptyList() - } + get() = allComponents.takeIf { destinationIsActive } ?: emptyList() init { observeLifeCycle()