Skip to content

Commit

Permalink
Fixed Modo.init to return same instance for a same process
Browse files Browse the repository at this point in the history
  • Loading branch information
ikarenkov committed May 22, 2024
1 parent 499a732 commit 5b96d00
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 4 deletions.
File renamed without changes.
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[versions]
leakcanaryAndroid = "2.14"
modo = "0.9.0-dev9"
modo = "0.9.0-dev10"
androidGradlePlugin = "8.4.0"
detektComposeVersion = "0.3.20"
detektVersion = "1.23.6"
Expand Down
22 changes: 19 additions & 3 deletions modo-compose/src/main/java/com/github/terrakok/modo/Modo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,33 @@ object Modo {
}

/**
* Entrance point for screen integration.
* Creates [RootScreen] provided by [rootScreenProvider], if there is no data in [savedState] or in-memory.
* Otherwise [RootScreen] is firstly taking from memoryr and then restored from savedState, if there is no RootScreen in memory.
* Returns same instance of [RootScreen] for same process. A new instance returned only after process death.
* @param savedState - container with modo state and graph
* @param rootScreenProvider invokes when [savedState] is null and [inMemoryScreen] is null and we need to provide root screen.
*/
fun <T : Screen> init(savedState: Bundle?, inMemoryScreen: RootScreen<T>?, rootScreenProvider: () -> T): RootScreen<T> {
// taking saved state to obtain screenKey
val modoGraph = savedState?.getParcelable<RootScreen<T>>(MODO_GRAPH)
return if (modoGraph != null) {
restoreScreenCounter(savedState.getInt(MODO_SCREEN_COUNTER_KEY))
modoGraph
// If restoring after activity death, but not after process death, then [inMemoryScreen] is null, but we have cached object in rootScreens
// So we trying to restore it from memory and only if it is null - taking it from savedState.
val cachedRootScreen = rootScreens.get(modoGraph.screenKey)?.let { it as RootScreen<T> }
if (cachedRootScreen != null) {
cachedRootScreen
} else {
restoreScreenCounter(savedState.getInt(MODO_SCREEN_COUNTER_KEY))
modoGraph
}
} else {
// saved state is going to be null after taking fragment from backstack, beckause in this case
// 1. onSaveInstaneState is not called
// 2. View is destroyed
// 3. Fragment is not destroyed and have inMemoryScreen != null if it is not a first call
inMemoryScreen ?: RootScreen(rootScreenProvider())
}.also { rootScreen ->
rootScreens.put(rootScreen.screenKey, rootScreen)
}
}

Expand Down

0 comments on commit 5b96d00

Please sign in to comment.