Android: getChildDrawingOrder() returned invalid index 1 (child count is 1)
Asked Answered
P

3

10

This is the stacktrace:

Fatal Exception: java.lang.IndexOutOfBoundsException: getChildDrawingOrder() returned invalid index 1 (child count is 1)
   at android.view.ViewGroup.getAndVerifyPreorderedIndex(ViewGroup.java:1988)
   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4204)
   at android.view.View.draw(View.java:20373)
   at android.view.View.updateDisplayListIfDirty(View.java:19315)
   at android.view.View.draw(View.java:20093)
   at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
   at android.view.View.updateDisplayListIfDirty(View.java:19306)
   at android.view.View.draw(View.java:20093)
   at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
   at android.view.View.updateDisplayListIfDirty(View.java:19306)
   at android.view.View.draw(View.java:20093)
   at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4231)
   at android.view.View.draw(View.java:20373)
   at androidx.viewpager.widget.ViewPager.draw(ViewPager.java:2426)
   at android.view.View.updateDisplayListIfDirty(View.java:19315)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4405)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4385)
   at android.view.View.updateDisplayListIfDirty(View.java:19274)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4405)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4385)
   at android.view.View.updateDisplayListIfDirty(View.java:19274)
   at android.view.View.draw(View.java:20093)
   at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4231)
   at android.view.View.updateDisplayListIfDirty(View.java:19306)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4405)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4385)
   at android.view.View.updateDisplayListIfDirty(View.java:19274)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4405)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4385)
   at android.view.View.updateDisplayListIfDirty(View.java:19274)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4405)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4385)
   at android.view.View.updateDisplayListIfDirty(View.java:19274)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4405)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4385)
   at android.view.View.updateDisplayListIfDirty(View.java:19274)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4405)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4385)
   at android.view.View.updateDisplayListIfDirty(View.java:19274)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4405)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4385)
   at android.view.View.updateDisplayListIfDirty(View.java:19274)
   at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:686)
   at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:692)
   at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:800)
   at android.view.ViewRootImpl.draw(ViewRootImpl.java:3496)
   at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3283)
   at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2818)
   at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1780)
   at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7827)
   at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
   at android.view.Choreographer.doCallbacks(Choreographer.java:723)
   at android.view.Choreographer.doFrame(Choreographer.java:658)
   at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
   at android.os.Handler.handleCallback(Handler.java:789)
   at android.os.Handler.dispatchMessage(Handler.java:98)
   at android.os.Looper.loop(Looper.java:164)
   at android.app.ActivityThread.main(ActivityThread.java:6944)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

I can't seem to figure out how to trace this back to the problem. It seems to be something with a ViewGroup somewhere. I looked back at the code diff but I couldn't figure out exactly which one would cause this as none manipulate their children. Was wondering if anyone ran into this very vague error trace before.

Professed answered 1/5, 2019 at 22:53 Comment(4)
Copy pasting stacktrace without context is barely helpful, what are you doing in your app before it crashes and how does layout hierarchy look? – Klingensmith
The thing with this is I can't pinpoint where it's happening because it doesn't direct me to which view group it's happening in. And this goes back to many older versions and since then hundreds of layouts has been added. The only thing i see on fabric is the stack trace I just posted, unfortunately. I was hoping someone would have had a similar "vague" problem and figured out a fix for it, I've been trying to test which layout this is happening to for weeks. – Professed
I got this problem when I double-clicked quickly on links in a Webview on Android. If anyone has any idea how to solve this problem that would be awesome πŸ™. – Ventilate
I get this error when using Samsung Pen on my app – Machicolate
D
1

I also received this stacktrace with no clear trace back to my code.

The issue is that there is some sort of race condition when adding or removing views on a ViewGroup programmatically and when the ViewGroup is drawn.

In order to fix the issue or help diagnose it, search your codebase for api calls to ViewGroup#removeAllViews, ViewGroup#addView, ViewGroup#removeView. As other users pointed out in comments, its hard to help fix your specific case with just the stack trace. Do you mind updating the post to show some parts of your app where you call the following to help diagnose / fix your specific issue?

ViewGroup.removeAllViews()
ViewGroup.addView(...)
ViewGroup.removeView(...)

The fix that helped my app avoid this type of crash was changing these calls to toggle the visibility of the views inside the ViewGroup instead of adding / removing the views themselves. I.e inflate and add Views once and then toggle visiblity from there.

Example of my bad code using removeAllViews and addView:

    val materialButtonToggleGroup : MaterialButtonToggleGroup = binding.startRideFragmentToggle
    if (materialButtonToggleGroup.childCount != fareInfo.size) {
        materialButtonToggleGroup.removeAllViews()
        for (rideService in fareInfo) {
            val textView = LayoutInflater.from(requireContext())
                .inflate(R.layout.material_button_outlined, materialButtonToggleGroup, false) as Button
            materialButtonToggleGroup.addView(textView)
        }
    }

Code that fixed the issue (we never remove views, just set visibility to View.GONE if we have too many views):

    val materialButtonToggleGroup : MaterialButtonToggleGroup = binding.startRideFragmentToggle
    fareInfo.forEachIndexed { index, rideService ->
        if (index >= materialButtonToggleGroup.childCount) {
            val textView = LayoutInflater.from(requireContext())
                .inflate(
                    R.layout.material_button_outlined,
                    materialButtonToggleGroup,
                    false
                ) as Button
            materialButtonToggleGroup.addView(textView)
        }
    }

    for (i in 0 until materialButtonToggleGroup.childCount) {
        val toggleTabText = materialButtonToggleGroup.getChildAt(i)
        if (i < fareInfo.size) {
            toggleTabText.visibility = View.VISIBLE
        } else {
            toggleTabText.visibility = View.GONE
        }
    }
Dubonnet answered 16/2, 2023 at 19:9 Comment(0)
C
0

I've had similar issues with Fulguris. As noted in this answer, it appears related to manipulation of the view hierarchy during rendering. As hinted by their documentations, functions such as addView and removeView are not supposed to be called from rendering contexts. However what that means exactly is not clearly defined. In my case I was calling them from AnimatorListener.onAnimationEnd. While it appears to be working most of the time on most devices, it would occasionally results in IndexOutOfBoundsException.

My solution was to use View.post from onAnimationEnd to perform those kind of operations.

Clad answered 23/1 at 13:25 Comment(0)
N
0

If you are using MaterialButtonToggleGroup like @josacky, then isChildrenDrawingOrderEnabled=false will fix this crash. In ViewGroup.dispatchDraw ,final boolean customOrder = preorderedList == null && isChildrenDrawingOrderEnabled(); , then getAndVerifyPreorderedIndex() would skip the boundary check which throws exception.

Never answered 19/3 at 8:43 Comment(0)

© 2022 - 2024 β€” McMap. All rights reserved.