我想在一个只组合的应用程序中跟踪屏幕视图,所以没有活动,片段,只有可组合的函数。
我应该何时、如何调用屏幕跟踪如重火力点吗?
因为可组合函数的函数体在每次重组时执行,副作用也可以被重复调用,这些都不意味着真正的"视图",所以可组合函数可以是不可见的,或者只是可测量的。
您可以使用带有常量键的LaunchedEffect
或DisposableEffect
,例如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
回调。这样做将导致你的分析代码在你的应用程序的中心位置。