如何使用 Jetpack Compose UI 正确跟踪 Android 上的屏幕视图?

问题描述 投票:0回答:5

我想在仅撰写的应用程序中跟踪屏幕视图,因此没有活动、片段,只有可组合的功能。

我应该何时以及如何调用屏幕跟踪,例如用于火力基地?

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

android firebase google-analytics android-jetpack-compose firebase-analytics
5个回答
11
投票

您可以将

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
}

4
投票

如果您想发送基于生命周期事件的分析事件,您可以使用 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 */
}

1
投票

@Adrian K DisposableEffect,正如您的答案中的那样,即使您在惰性列中使用惰性行,也能很好地工作。

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

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

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


0
投票

如果您使用不同的 LifecycleAware 组件作为不同的 Activity 或包含可组合项的不同片段,那么 Carmen 的答案是正确的,但是,如果您仅使用一个 Activity 来在具有

Jetpack Navigation
的导航图中托管所有可组合项,则无需使用
lifecycleOwner
,下面是解释。

在 Activity 中使用 Jetpack Compose 时,

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

由于

LocalLifecycleOwner
.current 值将始终引用 Activity 的生命周期所有者,因此使用 Unit 作为关键参数将确保每当重构 TrackedScreen 可组合项或包含它的组件时都会触发
DisposableEffect

总而言之,如果使用

TrackedScreen
的可组合项始终在同一个
Activity
中执行,则可以省略生命周期Owner 参数并使用 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)
                }
        }
    }

0
投票

如果您使用

NavHostController
在“顶级”可组合项之间导航,则可以使用其
.addOnDestinationChangedListener
回调。这样做将导致您的分析代码位于应用程序中的中心位置。

© www.soinside.com 2019 - 2024. All rights reserved.