【问题标题】:How are Android activities handled with Jetpack Compose and Compose Navigation?Jetpack Compose 和 Compose Navigation 如何处理 Android 活动?
【发布时间】:2021-10-27 22:15:44
【问题描述】:

我目前正在研究 Jetpack Compose,试图使用现代 Android 架构组件构建功能丰富的应用程序。传统上,我的应用程序中的每个屏幕(或导航单元)要么是一个活动,要么是一个片段,每个都有自己的生命周期绑定,但使用 Jetpack Compose 和 Compose Navigation 库,我会做这样的事情:

MainActivity.kt:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val navController = rememberNavController()

            NavHost(navController = navController, startDestination = "main") {
                composable("main") { MainScreen(navController) }
                // More composable calls
            }
        }
    }
}

MainScreen 只是一个可组合的。我的问题是:

  • 对于这个可组合的“生命周期”,这里的等价物是什么?假设我想在加载屏幕、销毁屏幕等时执行一些操作。这可能与我有更多屏幕并在它们之间导航的情况更相关
  • 有没有办法在 Compose 和标准活动之间进行集成?也就是说,为屏幕定义活动,每个活动都是ComponentActivity 并定义自己的可组合布局?是否出于某种原因不鼓励这样做?

【问题讨论】:

    标签: android kotlin android-jetpack-compose


    【解决方案1】:

    Compose 应用程序旨在用于没有片段的单活动架构。

    您仍然可以拥有多个活动或片段并在每个活动或片段中使用setContent,但在这种情况下,活动之间的数据传输就落在了您的肩上。如果您要向以旧方式构建的现有应用程序添加新的 Compose 屏幕,请使用此方法。

    但是使用 Compose,使用 Compose Navigation 在单个 Activity 中完成所有导航要容易得多。更少的代码,由于没有不必要的代码层,更好的性能,易于传输数据等。

    要使用视图生命周期,请查看compose side-effects

    1. LaunchedEffect 可用于在视图出现时执行操作。它还运行在绑定到当前可组合项的协程上下文上:您可以轻松运行挂起函数,并且当视图从视图层次结构中消失时 - 协程将被取消。
    2. DisposableEffect 可用于订阅/取消订阅回调。

    当您旋转屏幕时,无论您按哪个键,所有效果都会重新启动。

    @Composable
    fun MainScreen(navController: NavController) {
        LaunchedEffect(Unit) {
            println("LaunchedEffect: entered main")
            var i = 0
            // Just an example of coroutines usage
            // don't use this way to track screen disappearance
            // DisposableEffect is better for this
            try {
                while (true) {
                    delay(1000)
                    println("LaunchedEffect: ${i++} sec passed")
                }
            } catch (cancel: CancellationException) {
                println("LaunchedEffect: job cancelled")
            }
        }
        DisposableEffect(Unit) {
            println("DisposableEffect: entered main")
            onDispose {
                println("DisposableEffect: exited main")
            }
        }
    }
    

    另请注意,在这两种情况下,以及在撰写的许多其他情况下,您将key 传递给这些函数。这有助于组合理解何时应该重新计算值。在我的示例中,它是Unit,这意味着在视图消失之前它不会改变。但是如果你创建一个remember 值,使用视图模型中的另一个动态值,或者将另一个参数传递给可组合,你可以将它作为key 传递,这将取消当前的LaunchedEffect 作业并调用onDispose对于DisposableEffect,您的作业将使用更新的key 值重新启动。您可以传递任意数量的密钥。

    documentation 中阅读有关 Compose 状态的更多信息。

    【讨论】:

    • The Compose application is designed to be used in a single-activity architecture with no fragments. 是一个非常有用的声明。只是好奇,您在任何文档中的什么地方看到的?想看看我怎么会错过这么重要的声明。
    • @KevinLe-Khnle 我不确定我在哪里读到这个,但对我来说似乎很合乎逻辑。您可以进行 Compose 导航,并且使用片段或多个活动比使用纯 Compose 实现相同的功能要复杂得多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-23
    • 2020-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多