diff --git a/app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaApp.kt b/app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaApp.kt index b495056fc..50b5f57da 100644 --- a/app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaApp.kt +++ b/app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaApp.kt @@ -42,7 +42,6 @@ import androidx.compose.material3.windowsizeclass.WindowSizeClass import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Modifier @@ -55,8 +54,8 @@ import androidx.navigation.NavDestination.Companion.hierarchy import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import com.google.samples.apps.nowinandroid.core.ui.ClearRippleTheme +import com.google.samples.apps.nowinandroid.core.ui.JankMetricDisposableEffect import com.google.samples.apps.nowinandroid.core.ui.component.NiaBackground -import com.google.samples.apps.nowinandroid.core.ui.rememberMetricsStateHolder import com.google.samples.apps.nowinandroid.core.ui.theme.NiaTheme import com.google.samples.apps.nowinandroid.navigation.NiaNavHost import com.google.samples.apps.nowinandroid.navigation.NiaTopLevelNavigation @@ -68,8 +67,7 @@ import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination fun NiaApp(windowSizeClass: WindowSizeClass) { NiaTheme { val navController = rememberNavController() - val metricsHolder = rememberMetricsStateHolder() - DisposableEffect(navController, metricsHolder) { + JankMetricDisposableEffect(navController) { metricsHolder -> val listener = NavController.OnDestinationChangedListener { _, destination, _ -> metricsHolder.state?.addState("Navigation", destination.route.toString()) } diff --git a/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/JankStatsExtensions.kt b/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/JankStatsExtensions.kt index 3d606b6a3..4b1459a2d 100644 --- a/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/JankStatsExtensions.kt +++ b/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/JankStatsExtensions.kt @@ -17,6 +17,9 @@ package com.google.samples.apps.nowinandroid.core.ui import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.DisposableEffectResult +import androidx.compose.runtime.DisposableEffectScope import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.remember import androidx.compose.ui.platform.LocalView @@ -52,3 +55,19 @@ fun JankMetricEffect( reportMetric(metrics) } } + +/** + * Convenience function to work with [PerformanceMetricsState] state that needs to be cleaned up. + * The side effect is re-launched if any of the [keys] value is not equal to the previous composition. + */ +@Composable +fun JankMetricDisposableEffect( + vararg keys: Any?, + reportMetric: DisposableEffectScope.(state: PerformanceMetricsState.MetricsStateHolder) -> DisposableEffectResult +) { + val metrics = rememberMetricsStateHolder() + DisposableEffect(metrics, *keys) { + reportMetric(this, metrics) + } +} + diff --git a/feature-interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/InterestsScreen.kt b/feature-interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/InterestsScreen.kt index eeba8e53d..3a1c3ac7b 100644 --- a/feature-interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/InterestsScreen.kt +++ b/feature-interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/InterestsScreen.kt @@ -29,7 +29,6 @@ import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material.icons.filled.Search import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment @@ -37,11 +36,11 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel +import com.google.samples.apps.nowinandroid.core.ui.JankMetricDisposableEffect import com.google.samples.apps.nowinandroid.core.ui.LoadingWheel import com.google.samples.apps.nowinandroid.core.ui.component.NiaTab import com.google.samples.apps.nowinandroid.core.ui.component.NiaTabRow import com.google.samples.apps.nowinandroid.core.ui.component.NiaTopAppBar -import com.google.samples.apps.nowinandroid.core.ui.rememberMetricsStateHolder @Composable fun InterestsRoute( @@ -63,8 +62,7 @@ fun InterestsRoute( modifier = modifier ) - val metricsHolder = rememberMetricsStateHolder() - DisposableEffect(tabState, metricsHolder) { + JankMetricDisposableEffect(tabState) { metricsHolder -> metricsHolder.state?.addState("Interests:TabState", "currentIndex:${tabState.currentIndex}") onDispose {