android - FragmentManager IndexOutOfBoundsException 无法恢复 Activity 崩溃

标签 android crash android-lifecycle android-8.0-oreo

这可能是一个转移注意力的问题,但我的应用程序充满了无 UI 任务 fragment ,用于执行大多数网络操作并围绕 Activity 生命周期工作。此处描述了此类架构的示例。 https://stackoverflow.com/a/12303649/2662474

在运行 Oreo 8.0 的新 Google Pixel 和 Nexus 手机上,该应用程序已经开始以一种非常难以调试的方式在许多不同的 Activity 恢复时崩溃,并且看起来像是引入的低级别 Android 错误。它不会发生在任何以前的操作系统版本上。

Fatal Exception: java.lang.RuntimeException: Unable to resume activity {com.mycompany.shop/com.mycompany.shop.activity.MainNavActivity}: java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
       at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3645)
       at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3685)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1643)
       at android.os.Handler.dispatchMessage(Handler.java:105)
       at android.os.Looper.loop(Looper.java:164)
       at android.app.ActivityThread.main(ActivityThread.java:6541)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
       at java.util.ArrayList.get(ArrayList.java:437)
       at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1610)
       at android.app.FragmentManagerImpl.dispatchMoveToState(FragmentManager.java:3035)
       at android.app.FragmentManagerImpl.dispatchResume(FragmentManager.java:3001)
       at android.app.FragmentController.dispatchResume(FragmentController.java:200)
       at android.app.Activity.performResume(Activity.java:7100)
       at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3620)
       at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3685)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1643)
       at android.os.Handler.dispatchMessage(Handler.java:105)
       at android.os.Looper.loop(Looper.java:164)
       at android.app.ActivityThread.main(ActivityThread.java:6541)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

请帮忙!

最佳答案

您的错误发生在 FragmentManager 中的嵌套类 FragmentManagerImpl 的方法 moveToState() 中。导致错误的具体代码是以下几行中的 Fragment f = mAdded.get(i):

final int numAdded = mAdded.size();
for (int i = 0; i < numAdded; i++) {
    Fragment f = mAdded.get(i); // [causing the error]
    moveFragmentToExpectedState(f);
    if (f.mLoaderManager != null) {
        loadersRunning |= f.mLoaderManager.hasRunningLoaders();
    }
}

mAdded 是添加 fragment 的列表,定义为:

ArrayList<Fragment> mAdded;

发生错误时,i == 3 和 mAdded Arraylist 的大小小于该值。 (错误行:“java.lang.IndexOutOfBoundsException: Index: 3, Size: 3”)要发生这种情况,必须从 mAdded 中的某处删除 fragment ,特别是在某处以 moveFragmentToExpectedState() 开头的调用链。

您提到您的应用“围绕 Activity 生命周期工作”。根据 Oreo 8.0,您可能正在将 fragment 置于意想不到的状态。我建议您将您的应用程序放入调试器并在此 for 循环中设置一个断点。然后,您可以尝试追踪 Arraylist mAdded 被更改的位置。这至少应该为您指明解决方案的正确方向。

顺便说一句,API 26 的源代码已经发布。它可以帮助您进行调试。


更新:从源代码来看,API 26 中的 FragmentManger 区域已经从 API 25 中的版本中获得了大量工作。您可能需要采纳 azizbekian 的建议并移动到 android.support.v4.app.Fragment。支持版本似乎比 API 26 更符合 API 25。这可能是权宜之计,直到您找出根本原因。

关于您当前的实现,我会寻找任何会在 onResume() 处理期间移除或分离 fragment 的东西,特别是如果它是在 UI 线程之外完成的,并且可能是在非线程中完成的 -安全的方式。寻找任何直接或间接调用 FragmentManagerremoveFragment()detachFragment() 的东西,因为这些似乎是 fragment 唯一的地方从 mAdded 中删除。

关于android - FragmentManager IndexOutOfBoundsException 无法恢复 Activity 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46436235/

相关文章:

java - Android 操作系统覆盖应用程序字体

ios6 - 从 Crittercism 获得了这份崩溃报告。无法找出崩溃的原因。任何提示都会有所帮助

android - 在 Android 中伪造应用程序崩溃

c++ - Windows 中的 Exe 在调用 GetWindowsDirectory 时 append wstring 时崩溃

android - onBackPressed() 覆盖

android - 如果我在 onCreate 期间启动 AsyncTask,它什么时候开始执行?

安卓 : How to make Popup Menu to have same width as its anchor?

1490086 字节的 Android 错误 : I/dalvikvm-heap: Grow heap (frag case) to 16. 159MB

java - 从另一个线程运行线程

android - RecyclerView Adapter 在更新不同的 observable 时更改列表