ArrayList 错误,应用程序崩溃

ArrayList Error, App Crashes

我有以下问题。我有两个 fragment 应用程序,其中一个静态 arraylist 用于两个 fragments

错误的发生可以这样描述:

  1. entries 添加到 arraylist (FragmentA)
  2. 点击按钮,在图表中显示arraylist片段B
  3. 返回片段A,添加另一个entriearraylist -> 错误发生,app崩溃

片段的代码是这样的:

我得到的错误是这样的:

java.lang.ArrayIndexOutOfBoundsException:长度=1;索引=1

如果有经验的高手能帮帮我,我将不胜感激。 谢谢。

更新:包含错误堆栈

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.example.nextpietwo, PID: 2528
                  java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
                      at com.github.mikephil.charting.renderer.PieChartRenderer.drawDataSet(PieChartRenderer.java:244)
                      at com.github.mikephil.charting.renderer.PieChartRenderer.drawData(PieChartRenderer.java:147)
                      at com.github.mikephil.charting.charts.PieChart.onDraw(PieChart.java:126)
                      at android.view.View.draw(View.java:17185)
                      at android.view.View.updateDisplayListIfDirty(View.java:16167)
                      at android.view.View.draw(View.java:16951)
                      at android.view.ViewGroup.drawChild(ViewGroup.java:3727)
                      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3513)
                      at android.view.View.updateDisplayListIfDirty(View.java:16162)
                      at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3711)
                      at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3691)
                      at android.view.View.updateDisplayListIfDirty(View.java:16130)
                      at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3711)
                      at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3691)
                      at android.view.View.updateDisplayListIfDirty(View.java:16130)
                      at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3711)
                      at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3691)
                      at android.view.View.updateDisplayListIfDirty(View.java:16130)
                      at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3711)
                      at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3691)
                      at android.view.View.updateDisplayListIfDirty(View.java:16130)
                      at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3711)
                      at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3691)
                      at android.view.View.updateDisplayListIfDirty(View.java:16130)
                      at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3711)
                      at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3691)
                      at android.view.View.updateDisplayListIfDirty(View.java:16130)
                      at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3711)
                      at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3691)
                      at android.view.View.updateDisplayListIfDirty(View.java:16130)
                      at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:648)
                      at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:654)
                      at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:762)
                      at android.view.ViewRootImpl.draw(ViewRootImpl.java:2800)
                      at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2608)
                      at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2215)
                      at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1254)
                      at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6337)
                      at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
                      at android.view.Choreographer.doCallbacks(Choreographer.java:686)
                      at android.view.Choreographer.doFrame(Choreographer.java:621)
                      at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
                      at android.os.Handler.handleCallback(Handler.java:751)
                      at android.os.Handler.dispatchMessage(Handler.java:95)
                      at android.os.Looper.loop(Looper.java:154)
                      at android.app.ActivityThread.main(ActivityThread.java:6119)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

MPAndroid图表无法保护您免受非 separating model and view layers and from issues with the managing the lifecycles of Fragments and Activities. Please note that "communicating" between Fragments (such as one Fragment manipulating the data of another) is not recommended by Google:

的影响

Two Fragments should never communicate directly

虽然Entry可能看起来像模型层的成员,但实际上它被设计为与属于视图层的PieChart紧密耦合。它绝对应该 而不是 比它关联的视图更长寿,如果你想避免 ArrayIndexOutOfBoundsException 之类的错误,支持列表的生命周期应该与中的片段的生命周期一致它被使用。这并不意味着一旦 List<Entry> 成为 PieChart 的一部分,您就永远不能 add/remove - MPAndroidChart 将允许您在上述限制范围内执行此操作。

为了修复上述错误,我建议采用一种不同于共享静态对象的方法,这在 Android 中几乎不是一个好主意。相反,您可以共享一个单独的模型层,其中包含您将用于构建 List<Entry> 的数据。当 Fragment A 更新模型时,您可以使用事件触发从 Fragment B 中的数据重建图表。

您在评论中声明您正在使用 ViewPagerViewPager 使用 fragmentTransaction.show().hide() 并且通常使片段保持在恢复状态。也许最简单的解决方案是覆盖 onHiddenChanged,因为当 ViewPager 切换到新页面时总是会调用它。我认为(不是 100% 确定)您还需要在 onActivityCreated(View v).

中致电

所以,你会得到这样的东西:

@Override
onActivityCreated(View v) {
    //get updated model from Activity
    //rebuild chart from updated model
}

@Override 
onHiddenChanged(boolean hidden) {
    if (hidden == false) {
        //get updated model from Activity
        //rebuild chart from updated model
    }
}