1

I am getting IndexOutOfBoundsException when I remove items in mutableStateListOf, where MyType is some custom Type. There are almost around 250 items in myList. The items are removed in a loop. Almost 6 elements are visible in viewport at one time. When the item count reaches less than or equal to 6(with scroll position at top) then this exception is raised and the application crashes.

Furthoremore, the application is crashed only when Listview is the active screen. Otherwise it doesnot crash/ this indexoutofboundexception is not raised. I have debugged the application logic and made sure that there are checks to ignore any update/add/remove request with index larger than list size. I suspect the exception is raised during recomposition only. Another behaviour I observed is when the List is scrolled to the bottom and the items are removed, then this exception is already raised at the very beginning of the loop. Please have a look at the stack trace.

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)

I am using the following jetpack compose version:

`ext.composeCompilerVersion = 1.4.3

ext { compose_version = composeCompilerVersion //COMPOSE COMPILER VERSION }`

Following is the example composable function for displaying 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()
    }

I tried reproducing the behaviour. First thing I found out was that this exception is not raised if ListView is not the active screen(because Listview is not recomposed). Also after looking at the stack trace my assumption is that this issue has something to do with the internal jetpack compose libraries or the way I have implemented the composable function i.e. Lazycolumn.

Mansoor
  • 11
  • 1

1 Answers1

0

**In your code try using this below code and run **

@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()
                                    )


                    }
                }
            }
        }
    }
}

}

D_K
  • 152
  • 2
  • 9