Expose onRouteLifecycleStateChanged(Lifecycle.State) API to allow ActivityStoreContext.isRouteStarted() and ActivityStoreContext.isRouteResumed() keep functioning under non-Fragment navigation host (Compose Nav 3).#515
Conversation
…ivityStoreContext.isRouteStarted() and ActivityStoreContext.isRouteResumed() keep functioning under non-Fragment navigation host (Compose Nav 3).
There was a problem hiding this comment.
formula-android/src/main/java/com/instacart/formula/android/internal/ActivityManager.kt:77
ActivityStoreContextImpl now keeps route lifecycle state until a route reports DESTROYED, but ActivityManager is reused across configuration changes via AppManager. In the non-Fragment host path, there is no automatic equivalent of NavigationFlowRenderView.onFragmentViewDestroyed(), so on activity recreation this delegate can retain stale STARTED/RESUMED entries from the previous activity instance. That means isRouteStarted() / isRouteResumed() can replay true for routes that no longer exist until the new host explicitly re-drives every route. Should we clear the stored route lifecycle state here on activity destroy, or otherwise prove recreation is handled correctly for the new API?
JaCoCo Code Coverage 93.83% ✅
Generated by 🚫 Danger |
📊 Benchmark Comparison ReportSummary
🎉 Performance Improvements
No significant changes (4 benchmarks)
Regressions: ±10% with non-overlapping confidence intervals. Improvements: ±10% change only. Generated by 🚫 Danger |
Good catch - was addressed. |
| private var activity: Activity? = null | ||
| private var hasStarted: Boolean = false | ||
| private val fragmentLifecycleStates = mutableMapOf<String, Lifecycle.State>() | ||
| private val routeLifecycleStates = mutableMapOf<String, Lifecycle.State>() |
There was a problem hiding this comment.
few fragment -> route renames while I'm here
| fun attachActivity(activity: Activity) { | ||
| hasStarted = false | ||
| this.activity = activity | ||
| clearRouteLifecycleState() |
There was a problem hiding this comment.
Clearing on new Activity attach rather than on old Activity detach - to cover races when detach happens after attach.
| @MainThread | ||
| fun onRouteLifecycleStateChanged(routeId: RouteId<*>, state: Lifecycle.State) { | ||
| onRouteLifecycleState?.invoke(routeId, state) | ||
| } |
There was a problem hiding this comment.
New public API for non-Fragment navigation hosts.
| import kotlinx.coroutines.rx3.asObservable | ||
| import kotlinx.coroutines.test.runTest |
There was a problem hiding this comment.
Removing redundant Flow->Observable conversion and switching to turbine tests.
| * is reused across configuration changes (see [AppManager]), without this the delegate would | ||
| * retain stale STARTED/RESUMED entries from the previous activity instance. | ||
| */ | ||
| fun clearRouteLifecycleState() { |
There was a problem hiding this comment.
I'm not a fan of this logic - I worry it might break fragment logic in an unintuitive way.
No description provided.