防止 LaunchedEffect 在配置更改时重新运行

Abh*_*nav 13 android kotlin android-jetpack android-jetpack-compose

我只想在加载可组合项时运行代码一次。因此,我使用 LaunchedEffect 并将 key 设置为 true 来实现此目的。

LaunchedEffect(true) {
    // do API call
}
Run Code Online (Sandbox Code Playgroud)

该代码工作正常,但每当有任何配置更改(例如屏幕旋转)时,都会再次执行该代码。如果配置更改,如何防止它再次运行?

Phi*_*hov 16

最简单的解决方案是存储有关您是否使用 API 调用的信息rememberSaveable:它会在配置更改时生效。

var initialApiCalled by rememberSaveable { mutableStateOf(false) }
if (!initialApiCalled) {
    LaunchedEffect(Unit) {
        // do API call
        initialApiCalled = false
    }
}
Run Code Online (Sandbox Code Playgroud)

此解决方案的缺点是,如果在 API 调用完成之前配置发生更改,LaunchedEffect协程将被取消,您的 API 调用也将被取消。

最干净的解决方案是使用视图模型,并在其中执行 API 调用init

class ScreenViewModel: ViewModel() {
    init {
        viewModelScope.launch {
            // do API call
        }
    }
}

@Composable
fun Screen(viewModel: ScreenViewModel = viewModel()) {
    
}
Run Code Online (Sandbox Code Playgroud)

官方文档推荐像这样传递视图模型作为参数。在产品代码中,您不需要向该视图传递任何参数,只需这样调用即可Screen():视图模型将通过默认参数创建viewModel()。它被移动到测试/预览功能的参数,如本答案所示。

  • @Johann 请先完成 Compose 教程 (2认同)