MPAndroidChart v3.1.0 Kotlin开发折线图抛出NegativeArraySizeException解决方案
MPAndroidChart折线图NegativeArraySizeException异常解决
问题描述
在Kotlin项目中引入com.github.PhilJay:MPAndroidChart:v3.1.0依赖开发折线图功能时,触发无业务代码指向的崩溃,谷歌检索到的公开方案、Stack Overflow相关问题、官方GitHub issue#2403提供的解决方案均无法解决问题。
崩溃日志
2021-06-29 11:57:35.319 com.example.myApp E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.myApp, PID: 15886 java.lang.NegativeArraySizeException: -58 at com.github.mikephil.charting.utils.Transformer.generateTransformedValuesLine(Transformer.java:178) at com.github.mikephil.charting.renderer.LineChartRenderer.drawValues(LineChartRenderer.java:549) at com.github.mikephil.charting.charts.BarLineChartBase.onDraw(BarLineChartBase.java:278) at android.view.View.draw(View.java:23901) at android.view.View.updateDisplayListIfDirty(View.java:22776) at android.view.View.draw(View.java:23631) at android.view.ViewGroup.drawChild(ViewGroup.java:5336) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:5093) at android.view.View.updateDisplayListIfDirty(View.java:22762) at android.view.View.draw(View.java:23631) at android.view.ViewGroup.drawChild(ViewGroup.java:5336) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:5093) at android.view.View.updateDisplayListIfDirty(View.java:22762) at android.view.View.draw(View.java:23631) at android.view.ViewGroup.drawChild(ViewGroup.java:5336) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:5093) at android.view.View.draw(View.java:23904) at android.view.View.updateDisplayListIfDirty(View.java:22776) at android.view.View.draw(View.java:23631) at android.view.ViewGroup.drawChild(ViewGroup.java:5336) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:5093) at android.view.View.updateDisplayListIfDirty(View.java:22762) at android.view.View.draw(View.java:23631) at android.view.ViewGroup.drawChild(ViewGroup.java:5336) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:5093) at android.view.View.updateDisplayListIfDirty(View.java:22762) at android.view.View.draw(View.java:23631) at android.view.ViewGroup.drawChild(ViewGroup.java:5336) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:5093) at android.view.View.updateDisplayListIfDirty(View.java:22762) at android.view.View.draw(View.java:23631) at android.view.ViewGroup.drawChild(ViewGroup.java:5336) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:5093) at android.view.View.updateDisplayListIfDirty(View.java:22762) at android.view.View.draw(View.java:23631) at android.view.ViewGroup.drawChild(ViewGroup.java:5336) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:5093) at android.view.View.draw(View.java:23904) at com.android.internal.policy.DecorView.draw(DecorView.java:1282) at android.view.View.updateDisplayListIfDirty(View.java:22776) at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:579) at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:585) at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:662) at android.view.ViewRootImpl.draw(ViewRootImpl.java:4994) at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:4701) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3818) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2575) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9916) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1010) at android.view.Choreographer.doCallbacks(Choreographer.java:809) at android.view.Choreographer.doFrame(Choreographer.java:744) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:995) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:246) at android.app.ActivityThread.main(ActivityThread.java:8512) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
原始业务代码
private fun setMountain(mChart: LineChart){ val entries = ArrayList<Entry>() entries.add(Entry(20.9f, 100f)) entries.add(Entry(20.1f, 304f)) entries.add(Entry(19.4f, 609f)) entries.add(Entry(18.6f, 914f)) entries.add(Entry(17.9f, 1219f)) entries.add(Entry(17.3f, 1524f)) entries.add(Entry(16.6f, 1828f)) entries.add(Entry(16f, 2133f)) entries.add(Entry(15.4f, 2438f)) entries.add(Entry(14.8f, 2743f)) entries.add(Entry(14.3f, 3048f)) entries.add(Entry(13.7f, 3352f)) entries.add(Entry(13.2f, 3657f)) entries.add(Entry(12.7f, 3962f)) entries.add(Entry(12.3f, 4267f)) entries.add(Entry(11.8f, 4572f)) entries.add(Entry(11.4f, 4876f)) entries.add(Entry(11f, 5181f)) entries.add(Entry(10.5f, 5486f)) entries.add(Entry(10.1f, 5791f)) entries.add(Entry(9.7f, 6096f)) entries.add(Entry(9.4f, 6400f)) entries.add(Entry(9f, 6705f)) entries.add(Entry(8.7f, 7010f)) entries.add(Entry(8.4f, 7315f)) entries.add(Entry(8.1f, 7620f)) entries.add(Entry(7.8f, 7924f)) entries.add(Entry(7.5f,8229f)) entries.add(Entry(7.2f,8534f)) entries.add(Entry(6.9f,8839f)) entries.add(Entry(6.3f,9144f)) val dataSet = LineDataSet(entries, "label") mChart.data = LineData(dataSet) mChart.invalidate() mChart.xAxis.position = XAxis.XAxisPosition.BOTTOM }
问题根因
MPAndroidChart底层绘制折线图时,默认要求Entry集合的X值必须为严格升序排列,如果X值顺序不符合要求,内部计算绘制用数组长度时会出现负数,进而触发NegativeArraySizeException。即使肉眼观察Entry的X值已经是有序状态,浮点精度误差、排序方向错误、插入顺序的细微问题都可能导致底层校验不通过。
解决方案
在构造LineDataSet之前,对Entry集合执行X轴升序排序,添加代码:Collections.sort(entries, EntryXComparator())
修正后代码
private fun setMountain(mChart: LineChart){ val entries = ArrayList<Entry>() entries.add(Entry(20.9f, 100f)) entries.add(Entry(20.1f, 304f)) entries.add(Entry(19.4f, 609f)) entries.add(Entry(18.6f, 914f)) entries.add(Entry(17.9f, 1219f)) entries.add(Entry(17.3f, 1524f)) entries.add(Entry(16.6f, 1828f)) entries.add(Entry(16f, 2133f)) entries.add(Entry(15.4f, 2438f)) entries.add(Entry(14.8f, 2743f)) entries.add(Entry(14.3f, 3048f)) entries.add(Entry(13.7f, 3352f)) entries.add(Entry(13.2f, 3657f)) entries.add(Entry(12.7f, 3962f)) entries.add(Entry(12.3f, 4267f)) entries.add(Entry(11.8f, 4572f)) entries.add(Entry(11.4f, 4876f)) entries.add(Entry(11f, 5181f)) entries.add(Entry(10.5f, 5486f)) entries.add(Entry(10.1f, 5791f)) entries.add(Entry(9.7f, 6096f)) entries.add(Entry(9.4f, 6400f)) entries.add(Entry(9f, 6705f)) entries.add(Entry(8.7f, 7010f)) entries.add(Entry(8.4f, 7315f)) entries.add(Entry(8.1f, 7620f)) entries.add(Entry(7.8f, 7924f)) entries.add(Entry(7.5f,8229f)) entries.add(Entry(7.2f,8534f)) entries.add(Entry(6.9f,8839f)) entries.add(Entry(6.3f,9144f)) // 添加X轴排序代码 Collections.sort(entries, EntryXComparator()) val dataSet = LineDataSet(entries, "label") mChart.data = LineData(dataSet) mChart.invalidate() mChart.xAxis.position = XAxis.XAxisPosition.BOTTOM }
内容的提问来源于stack exchange,提问作者Zachattack
相关产品推荐
相关产品推荐

