Jetpack Compose 和 Compose Navigation 如何处理 Android 活动?

Posted

技术标签:

【中文标题】Jetpack Compose 和 Compose Navigation 如何处理 Android 活动?【英文标题】:How are Android activities handled with Jetpack Compose and Compose Navigation? 【发布时间】: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 并定义自己的可组合布局?是否出于某种原因不鼓励这样做?

【问题讨论】:

【参考方案1】:

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

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

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

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

    LaunchedEffect 可用于在视图出现时执行操作。它还运行在绑定到当前可组合项的协程上下文上:您可以轻松运行挂起函数,并且当视图从视图层次结构中消失时 - 协程将被取消。 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 实现相同的功能要复杂得多。

以上是关于Jetpack Compose 和 Compose Navigation 如何处理 Android 活动?的主要内容,如果未能解决你的问题,请参考以下文章

Android Jetpack Compose学习—— Jetpack compose基础布局

Android Jetpack Compose学习—— Jetpack compose基础布局

Jetpack Compose 基础介绍

Jetpack Compose入门详解(实时更新)

Jetpack Compose 深入探索系列二:Compose 编译器

Jetpack Compose 深入探索系列四: Compose UI