由于 Lazycolumn Jetpack compose 中的 IndexOutOfBoundsException 而导致应用程序崩溃

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

当我删除 mutableStateListOf 中的项目时,我收到 IndexOutOfBoundsException,其中 MyType 是某种自定义类型。 myList 中有大约 250 项。这些项目将循环删除。几乎 6 个元素同时在视口中可见。当项目计数达到小于或等于 6(滚动位置位于顶部)时,会引发此异常并且应用程序崩溃。

此外,仅当 Listview 为活动屏幕时应用程序才会崩溃。否则它不会崩溃/不会引发此索引出界异常。我已经调试了应用程序逻辑,并确保进行检查以忽略索引大于列表大小的任何更新/添加/删除请求。我怀疑仅在重组期间引发异常。我观察到的另一个行为是,当列表滚动到底部并且项目被删除时,则在循环的最开始就已经引发了此异常。请查看堆栈跟踪。

FATAL EXCEPTION: main Process: com.XXX.YYY.ZZZ, PID: 16225 java.lang.IndexOutOfBoundsException: Index 6, size 6 at androidx.compose.foundation.lazy.layout.MutableIntervalList.checkIndexBounds(IntervalList.kt:177) at androidx.compose.foundation.lazy.layout.MutableIntervalList.get(IntervalList.kt:160) at androidx.compose.foundation.lazy.layout.DefaultLazyLayoutItemsProvider.getKey(LazyLayoutItemProvider.kt:232) at androidx.compose.foundation.lazy.LazyListItemProviderImpl.getKey(Unknown Source:2) at androidx.compose.foundation.lazy.layout.DefaultDelegatingLazyLayoutItemProvider.getKey(LazyLayoutItemProvider.kt:201) at androidx.compose.foundation.lazy.LazyListItemProviderKt$rememberLazyListItemProvider$1$1.getKey(Unknown Source:2) at androidx.compose.foundation.lazy.LazyMeasuredItemProvider.getAndMeasure-ZjPyQlc(LazyMeasuredItemProvider.kt:46) at androidx.compose.foundation.lazy.LazyListMeasureKt.measureLazyList-Hh3qtAg(LazyListMeasure.kt:164) at androidx.compose.foundation.lazy.LazyListKt$rememberLazyListMeasurePolicy$1$1.invoke-0kLqBqw(LazyList.kt:299) at androidx.compose.foundation.lazy.LazyListKt$rememberLazyListMeasurePolicy$1$1.invoke(LazyList.kt:190) at androidx.compose.foundation.lazy.layout.LazyLayoutKt$LazyLayout$1$2$1.invoke-0kLqBqw(LazyLayout.kt:71) at androidx.compose.foundation.lazy.layout.LazyLayoutKt$LazyLayout$1$2$1.invoke(LazyLayout.kt:69) at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$createMeasurePolicy$1.measure-3p2s80s(SubcomposeLayout.kt:598) at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:103) at androidx.compose.ui.graphics.SimpleGraphicsLayerModifier.measure-3p2s80s(GraphicsLayerModifier.kt:635) at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:155) at androidx.compose.foundation.layout.SizeModifier.measure-3p2s80s(Size.kt:781) at androidx.compose.ui.node.BackwardsCompatNode.measure-3p2s80s(BackwardsCompatNode.kt:323) at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:155) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1090) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1086) at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2200) at androidx.compose.runtime.snapshots.SnapshotStateObserver$observeReads$1$1.invoke(SnapshotStateObserver.kt:234) at androidx.compose.runtime.snapshots.SnapshotStateObserver$observeReads$1$1.invoke(SnapshotStateObserver.kt:230) at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:341) at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source:1) at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:230) at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:120) at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui_release(OwnerSnapshotObserver.kt:107) at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1086) at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:36) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:342) at androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui_release(LayoutNode.kt:1188) at androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui_release$default(LayoutNode.kt:1179) at androidx.compose.ui.node.MeasureAndLayoutDelegate.doRemeasure-sdFAvZA(MeasureAndLayoutDelegate.kt:309) at androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureAndRelayoutIfNeeded(MeasureAndLayoutDelegate.kt:434) 2023-07-03 15:30:55.228 16225-16225 AndroidRuntime          com.com.XXX.YYY.ZZZ  E      at androidx.compose.ui.node.MeasureAndLayoutDelegate.access$remeasureAndRelayoutIfNeeded(MeasureAndLayoutDelegate.kt:39) at androidx.compose.ui.node.MeasureAndLayoutDelegate.measureAndLayout(MeasureAndLayoutDelegate.kt:330) at androidx.compose.ui.platform.AndroidComposeView.measureAndLayout(AndroidComposeView.android.kt:805) at androidx.compose.ui.node.Owner.measureAndLayout$default(Owner.kt:221) at androidx.compose.ui.platform.AndroidComposeView.dispatchDraw(AndroidComposeView.android.kt:1035) at android.view.View.draw(View.java:21978) at android.view.View.updateDisplayListIfDirty(View.java:20852) at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4552) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4525) at android.view.View.updateDisplayListIfDirty(View.java:20812) at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4552) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4525) at android.view.View.updateDisplayListIfDirty(View.java:20812) at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4552) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4525) at android.view.View.updateDisplayListIfDirty(View.java:20812) at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4552) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4525) at android.view.View.updateDisplayListIfDirty(View.java:20812) at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:581) at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:587) at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:664) at android.view.ViewRootImpl.draw(ViewRootImpl.java:3773) at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3501) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2785) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1751) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7774) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:967) at android.view.Choreographer.doCallbacks(Choreographer.java:791) at android.view.Choreographer.doFrame(Choreographer.java:726) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:952) at android.os.Handler.handleCallback(Handler.java:883) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:7407) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

我正在使用以下jetpack compose版本:

`ext.composeCompilerVersion = 1.4.3

分机{ compose_version = composeCompilerVersion //组合编译器版本 }`

以下是用于显示 Listview 的示例可组合函数。

@Composable
fun ListViewInternalTest(
    elements2: List<MyType>
) {
    val listState = rememberLazyListState()

    LazyColumn(
        modifier = Modifier
            .height(pixelToDp(pixelSize = 792))
            .simpleVerticalScrollbar(state = listState),
        state = listState
    ) {

        items(
            elements2.size
        ) { index ->

            Column() {
                Row(
                    modifier = Modifier
                        .padding(start = pixelToDp(pixelSize = 35))
                        .height(pixelToDp(pixelSize = 130)),
                    verticalAlignment = Alignment.CenterVertically
                ) {

                    if(index < elements2.size) {
                        val element = elements2.getOrNull(index)

                        if (element != null) {

                            Text(
                                 modifier = Modifier
                                      .align(Alignment.Center)
                                      .width(pixelToDp(pixelSize = 202))
                                      .alpha(1f),
                                 text = "CH " + element.someMember.toString()
                                        )


                        }
                    }
                }
            }
        }
    }
}
val myList = mutableStateListOf<MyType>()

    fun insertItemToMyListAtIndex(index: Int, argMyType: MyType){

        if(index >= 0 && index <= myList.size) {
            myList.add(index, argMyType)
        }
    }

    fun updateItemInMyListAtIndex(index: Int, argMyType: MyType) {

        if(index>= 0 && index< myList .size) {
            myList[index] = argMyType
        }
    }

    fun removeItemFromMyList(index: Int) {

        if(index >= 0 && index < myList.size) {
            myList.removeAt(index)
        }
    }

    fun clearAllitemsInMyList(){
        myList.clear()
    }

我尝试重现这种行为。我发现的第一件事是,如果 ListView 不是活动屏幕,则不会引发此异常(因为 Listview 没有重组)。另外,在查看堆栈跟踪之后,我的假设是这个问题与内部 jetpack 撰写库或我实现可组合函数(即 Lazycolumn)的方式有关。

indexoutofboundsexception compose-recomposition android-jetpack-compose-lazy-column
2个回答
0
投票

**在您的代码中尝试使用下面的代码并运行**

@Composable
fun ListViewInternalTest(
elements2: List<MyType>
) {
    val listState = rememberLazyListState()

LazyColumn(
    modifier = Modifier
        .height(pixelToDp(pixelSize = 792))
        .simpleVerticalScrollbar(state = listState),
    state = listState
) {

    items(
        elements2
    ) { index, element ->

        Column() {
            Row(
                modifier = Modifier
                    .padding(start = pixelToDp(pixelSize = 35))
                    .height(pixelToDp(pixelSize = 130)),
                verticalAlignment = Alignment.CenterVertically
            ) {
                                          
                      Text(
                             modifier = Modifier
                                  .align(Alignment.Center)
                                  .width(pixelToDp(pixelSize = 202))
                                  .alpha(1f),
                             text = "CH " + element.someMember.toString()
                                    )


                    }
                }
            }
        }
    }
}

}


0
投票

如果您使用的版本 1.6.0-alpha08 存在关于 SubcomposeLayout 子组件的问题,请更新 compose Foundation 的新版本 1.6.0-beta01

© www.soinside.com 2019 - 2024. All rights reserved.