ITmob-Ly
发布于 2023-05-26 / 126 阅读
0

Jetpack Compose 中怎样处理生命周期事件?

使用 Android View 时

在使用 Android View 进行开发时,使用 ViewModel 管理 Fragment 或 Activity 的生命周期事件是很简单的。

在 Fragment 或 Activity 生命周期中将 ViewModel 添加为观察者,在 ViewModel 中实现 DefaultLifecycleObserver 接口并监听 onCreate,onStart 和 onStop 等生命周期事件即可。

如下代码是通过实现 DefaultLifecycleObserver 在 ViewModel 处理生命周期:

package cn.itmob.sample.ui

class HomeFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?,
    ): View {
        val homeViewModel: HomeViewModel by viewModels()
        lifecycle.addObserver(homeViewModel)
        // ...
    }
}
package cn.itmob.sample.ui

class HomeViewModel : ViewModel(), DefaultLifecycleObserver {

    private val _text = MutableLiveData<String>().apply {
        value = "This is home Fragment"
    }
    val text: LiveData<String> = _text

    override fun onCreate(owner: LifecycleOwner) {
        // TODO Handle lifecycle event
    }

    override fun onStart(owner: LifecycleOwner) {
        // TODO Handle lifecycle event
    }

    override fun onResume(owner: LifecycleOwner) {
        // TODO Handle lifecycle event
    }
}

使用 Jetpack Compose 时

使用 Jetpack Compose 开发应用时,官方推荐使用单个 Activity 并且不使用Fragment。使用 Activity 来管理可组合项,页面的导航是将一个可组合项换成另一个可组合项。因此,由于 Activity 比它管理的可组合项的生命周期更长,我们不能依赖 Activity 的生命周期来管理可组合项对应的 ViewModel 中依赖生命周期的任务(可组合项切换显示,它的生命周期发生了变化,但是 Activity 的生命周期并不一定会发生变化)。

如何在我们的 ViewModel 中实现类似于在视图系统中拥有的生命周期事件的可组合事件? DisposableEffect

先看代码:

@HiltViewModel
class HomeScreenViewModel @Inject constructor() : ViewModel() {
    fun onStart() {
        // TODO
    }

    fun onStop() {
        // TODO
    }
}

@Composable
fun HomeScreen(
    viewModel: HomeScreenViewModel,
    modifier: Modifier = Modifier,
) {
    val state = viewModel.state.collectAsState()

    DisposableEffect(Unit) {
        viewModel.onStart()
        onDispose { viewModel.onStop() }
    }
    // ...
}

DisposableEffect 可组合项会在进入组合时,运行 Effect 的 lambda,它会调用 ViewModel 的 onStart 方法,并注册一个 lambda 在可组合项离开组合时运行。这样,当可组合项离开该屏幕时,将调用 ViewModel 的 onStop。

DisposableEffect 的构造函数具有不同数量的参数,命名为 key。每当作为参数的任何 key 更改时,DisposableEffect 将调用其 onDispose,然后再次触发 DisposableEffect 的 lambda 表达式。