LaunchedEffect 中的代码抛出以下异常:“协程作用域离开了组合”

问题描述 投票:0回答:1

我有以下 UI 结构:

家长懒专栏:

TvLazyColumn(){
    itemsIndexed(rows){index, row ->
        MyLazyRow(mainViewModel, row, index)
    }
}

MyLazyRow.kt:

@Composable
fun MyLazyRow(mainViewModel : MainViewModel, row : List<rowItem>, listIndex : Int){
    val myLazyState = rememberTvLazyListState()
    val myRequesters by remember(row.size) { derivedStateOf { Array(row.size) { FocusRequester() } } }
    TvLazyRow(state = myLazyState){
        itemsIndexed(row){ index, rowItem ->
            MyItem(item = rowItem, modifier = Modifier.focusRequester(myRequesters[index]))
        }
    }
    LaunchedEffect(Unit){
        if (listIndex == mainViewModel.getLastFocussedRow.value){
            try {
                myLazyState.scrollToItem(dummyTargetFocus) //some randomly set const val
                myRequesters[dummyTargetFocus].requestFocus()
            } catch (ex: Exception) {
                ex.printStackTrace()
            }
        }  
    }
}

从代码中可以看出,我试图将焦点集中到 LazyRow 之一中的一张随机卡上,但是当 LaunchedEffect() 内的代码运行时,它会抛出相同的错误:

androidx.compose.runtime.LeftCompositionCancellationException: 协程作用域离开了组合

即使在确保我们请求焦点的可组合项:(惰性行和项目)位于屏幕上并且在焦点请求时已组合好。导致此错误的原因可能是什么?我可以有其他解决方法来解决此问题吗?

android kotlin android-jetpack-compose android-tv wordpress-jetpack
1个回答
0
投票

此异常仅意味着协程作用域被取消,因为

LaunchedEffect
已从“屏幕”中删除。基本上,如果该行因为不再可见而被回收,则
LaunchedEffect
的协程范围将被取消。这是预期的行为,因为您不希望 UI 元素启动比 UI 元素本身寿命更长的后台任务。

如果这是您想要的,您还可以在

rememberCoroutineScope()
之外使用
LazyColumn
,此范围将保持活动状态,直到 UI 的这一部分被删除,但在回收行时不会停止。

您的代码暗示您希望取消工作,但错误消息显示在日志中。您可以执行以下操作:

try {
   ...
} catch (e: CancellationException) {
   // Ignore
} catch (e: Exception) {
   ...
}
© www.soinside.com 2019 - 2024. All rights reserved.