这可能是一个红色的鲱鱼,但是我的应用程序充满了无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
除去片段的唯一位置。