如何正确跟踪和Jetpack组合UI屏幕视图在Android上吗?



我想在一个只组合的应用程序中跟踪屏幕视图,所以没有活动,片段,只有可组合的函数。

我应该何时、如何调用屏幕跟踪如重火力点吗?

因为可组合函数的函数体在每次重组时执行,副作用也可以被重复调用,这些都不意味着真正的"视图",所以可组合函数可以是不可见的,或者只是可测量的。

您可以使用带有常量键的LaunchedEffectDisposableEffect,例如Unit,在可组合物进入组合(DisposableEffect也在退出的情况下)时执行副作用,忽略重组。

// I don't think PascalCase would suit this method, as it suggests an on-screen element
@SuppressLint("ComposableNaming") 
@Composable
fun trackScreenView(name: String) {
DisposableEffect(Unit){
Log.d("SCREENTRACKING", "screen enter : $name")
onDispose { Log.d("SCREENTRACKING", "screen exit : $name") }
}
}
@Composable
fun Screen1() {
trackScreenView("Screen 1")
// your screen content here
}
@Composable
fun Screen2() {
trackScreenView("Screen 2")
// your screen content here
}

如果你想发送基于生命周期事件的分析事件,你可以使用LifecycleObserver。要在Compose中监听这些事件,可以在需要时使用DisposableEffect来注册和取消注册观察者。

@Composable
fun TrackedScreen(
name: String,
lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current,
) {
DisposableEffect(lifecycleOwner) {
val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_START) {
Firebase.analytics.logEvent(FirebaseAnalytics.Event.SCREEN_VIEW) {
param(FirebaseAnalytics.Param.SCREEN_NAME, name)
}
}
}
lifecycleOwner.lifecycle.addObserver(observer)
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
}
}
@Composable
fun HomeScreen() {
TrackedScreen("Home")

/* Home screen content */
}

@Adrian K处置效果,在你的回答将工作得很好,即使你使用延迟行在延迟列。

DisposableEffect(Unit){
Log.d("SCREENTRACKING", "screen enter : $name")
onDispose { Log.d("SCREENTRACKING", "screen exit : $name")
}

只有屏幕上的项目最初调用DisposableEffect,向下滚动或侧边滚动列表中的新项目被调用。对于细粒度印象数据,需要改进的一个问题是,滚动到之前已经渲染过的相同项目并不一定会再次调用DisposableEffect。

(本来会留下评论,但需要更多的声誉)

卡门的回答是正确的如果您使用的是不同的LifecycleAware组件包含可组合的不同的活动或不同的片段,但是,如果你只使用一个活动主机所有可组合在一个与Jetpack Navigation导航图,不需要使用lifecycleOwner,下面是解释。

当在Activity中使用Jetpack Compose时,LocalLifecycleOwner.current值将始终指向宿主Activity的生命周期所有者。在这种情况下,如果所有使用TrackedScreen的可组合项都在同一个Activity中执行,你可以安全地省略TrackedScreen可组合项中的lifecycleOwner参数,并使用Unit作为DisposableEffect中的关键参数。

由于LocalLifecycleOwner.current值将始终指向Activity的生命周期所有者,使用Unit作为关键参数将确保无论何时TrackedScreen可组合物被重组或包含它的组件被重组,DisposableEffect都会被触发。

总之,如果使用TrackedScreen的可组合组件总是在相同的Activity中执行,您可以省略lifecycleOwner参数,并使用Unit作为DisposableEffect中的关键参数。

@SuppressLint("ComposableNaming")
@Composable
fun trackScreen(
name: String
) {
DisposableEffect(Unit) {
onDispose {
// This block will be called when the effect is disposed
Firebase.analytics.logEvent(FirebaseAnalytics.Event.SCREEN_VIEW) {
param(FirebaseAnalytics.Param.SCREEN_NAME, name)
}
}
}
}

甚至还有另一种方法,每次你进入屏幕

@SuppressLint("ComposableNaming")
@Composable
fun trackScreen(
name: String
) {
DisposableEffect(Unit) {
onDispose {}
Firebase.analytics.logEvent(FirebaseAnalytics.Event.SCREEN_VIEW) {
param(FirebaseAnalytics.Param.SCREEN_NAME, name)
}
}
}

如果你使用NavHostController来导航,您可以使用它的.addOnDestinationChangedListener回调。这样做将导致你的分析代码在你的应用程序的中心位置。

最新更新