这可能是一个红色的鲱鱼,但是我的应用程序充满了无UI任务片段,可以执行大多数网络操作并在 Activity 生命周期内工作。此处描述了此类架构的示例。 https://stackoverflow.com/a/12303649/2662474

在运行Oreo 8.0的新Google Pixel和Nexus手机上,该应用程序在恢复许多不同 Activity 后开始崩溃,其方式非常难以调试,并且似乎是引入的低级Android错误。在任何以前的OS版本中都不会发生这种情况。

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)

请帮忙!

最佳答案

您的错误发生在moveToState()中的嵌套类FragmentManagerImpl的方法FragmentManager中。在以下各行中,导致erorr的特定代码为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是添加的片段的列表,定义为:
ArrayList<Fragment> mAdded;

发生错误时,i == 3和mAdded Arraylist的大小会小于此值。 (错误行:“java.lang.IndexOutOfBoundsException:索引:3,大小:3”)为此,必须在此for循环内的某个位置(特别是从mAdded开头的调用链中)的moveFragmentToExpectedState()中删除一个片段。

您提到您的应用程序是“在 Activity 生命周期内工作”。根据Oreo 8.0,也许您正在将碎片变成意外状态。我建议您将应用程序放入调试器,并在此for循环中设置一个断点。然后,您可以尝试跟踪Arraylist mAdded的更改位置。这至少应该为您指出解决方案的正确方向。

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

更新:通过查看源代码,API 26中的FragmentManger区域已从API 25中的版本获得了实质性的工作。您可能希望采纳azizbekian的建议,然后转到android.support.v4.app.Fragment。支持版本似乎更符合API 25,而不是API26。在您找出根本原因之前,这可能是一个权宜之计。

关于您当前的实现,我会寻找在onResume()处理期间会删除或分离片段的任何内容,尤其是如果它是在UI线程之外完成的,并且可能是以非线程安全的方式完成的。寻找直接或间接调用removeFragment()detachFragment()FragmentManager的任何东西,因为这些似乎是从mAdded除去片段的唯一位置。

10-07 22:21