Jetpack Compose下的生命周期

冰岩作坊 March 10, 2024

Jetpack Compose下的生命周期

当我们使用Jetpack Compose进行开发时,经常会遇到一些生命周期相关的问题,以下是一些生命周期相关问题的探索。

ViewModel的生命周期:

* ViewModel是一个用于存储和管理与UI相关的数据的类。它的生命周期与关联的Activity或Fragment不同。当Activity或Fragment被销毁时,ViewModel会继续存在,并且在新的Activity或Fragment实例创建时保持不变。

如下代码,MyViewModel仅与MyScreen进行绑定。当MyScreen首次创建时,MyViewModel会被创建,当MyScreen出栈时,它会被销毁。但当有其他Composable函数入栈时,MyScreen仍在栈中,因此MyViewModel不会销毁,仍会被保留。

但若是重新创建一个MyScreen,由于vm:MyViewModel=viewModel()使用的是依赖注入的机理,MyViewModel不会重新创建,而是调用唯一的一个MyViewModel

class MyViewModel:ViewModel(){}@Composablefun MyScreen()

Composable函数的生命周期:

如以下代码,MainScreen会在创建时执行 a = remember,在a.intValue = 2被调用时,由于该被引用的MutlableState类型的数据发生变化,Composalbe函数会发生重组。

当调用nav.jump(AppRoute.MY_FEED)时,MainScreen函数会被FeedScreen压栈。此时FeedScreen进入栈顶,MainScreen函数会被销毁,只留标识符在栈里,数据被销毁。

当在FeedScreen中调用nav.pop()时,FeedScreen会出栈,MainScreen会重新进入栈顶。此时的MainScreen会重新创建。

例如,当你在MainScreen点击按钮,将a的值改为2后,跳转到FeedScreen,再跳转回来,a的值会重新执行remember而被重新赋值为1。

因此,若想跳转到其他界面再回来时,界面的数据不发生变化,就要把数据保留在ViewModel里而不是使用remember{}进行保留。

@Composablefun MainScreen(    vm : MainViewModel = viewModel(),    nav:NavHostController)    Button(onClick = )     nav.jump(AppRoute.MY_FEED)}@Composablefun FeedScreen(    vm:FeedViewModel= viewModel(),    nav: NavHostController)    nav.pop()}

ViewModel的生命周期和Activity的生命周期的关系:

在开发中遇到的生命周期问题

@Composablefun MyScreen(    vm : MyViewModel = viewModel())    a.intValue = 2}

如以下代码,每次重组后,打印a的指针值,会是一样的,而打印b的指针值,会不同。

这种情况下尤其要注意回调的情况。因为在Kotlin里,回调使用的上下文的变量是将引用(指针)传入

@Composablefun MyScreen(    vm : MyViewModel = viewModel())    val b = MediaPlayer()    println(a)    println(b)}