Trying to create real time GraphView Line and getting java.util.ConcurrentModificationException

130 views Asked by At

I'm trying to make a graph in real time, but I get a java.util.ConcurrentModificationException error. If you set a high delay thread.sleep(500), then the chart will fill correctly, but if you set thread.sleep(100) or less, you always get an error after drawing 200-400 points, in total there are 2000 points in the chart

I create a graph in doInBackground()

Code:

public class MainActivity extends AppCompatActivity {

    private final String ecgData = "ecg2.json";
    private Button bt_graph_zoom;
    private GraphView graph;

    class GraphCreator extends AsyncTask<String, Void, Void> {

        @Override
        protected Void doInBackground(String... strings) {
            String json = null;
            try {
                InputStream inputStream = getAssets().open(strings[0]);
                byte[] data = new byte[inputStream.available()];
                inputStream.read(data);
                inputStream.close();
                json = new String(data, StandardCharsets.UTF_8);
                JSONObject jsonObject = new JSONObject(json);
                JSONArray jsonArray = jsonObject.getJSONArray("ecg");
                LineGraphSeries<DataPoint> series = new LineGraphSeries<>();
                graph.addSeries(series);
                series.setTitle("Зашумленный сигнал ЭКГ");
                series.setAnimated(true);
                for (int i = 0; i < 2000; i++) {
                    Thread.sleep(50);
                    JSONObject obj = jsonArray.getJSONObject(i);
                    series.appendData(new DataPoint(i,obj.getDouble("y")),false,2000);
                }
            } catch (IOException | JSONException | InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        graph = findViewById(R.id.graph);
        graph.setTitle("Исходный сигнал ЭКГ");
        graph.setTitleTextSize(55);
        graph.getViewport().setYAxisBoundsManual(true);
        graph.getViewport().calcCompleteRange();
        graph.getViewport().setMinY(-1);
        graph.getViewport().setMaxY(1.6);
        graph.getLegendRenderer().setVisible(true);
        graph.getLegendRenderer().setAlign(LegendRenderer.LegendAlign.TOP);
        graph.getGridLabelRenderer().setHorizontalAxisTitle("Отсчеты");
        graph.getGridLabelRenderer().setVerticalAxisTitle("Напряжение (мВ)");
        graph.getGridLabelRenderer().setHorizontalAxisTitleTextSize(55);
        graph.getGridLabelRenderer().setVerticalAxisTitleTextSize(55);
        graph.getGridLabelRenderer().setPadding(60);
        bt_graph_zoom = findViewById(R.id.bt_graph_zoom);
        bt_graph_zoom.setOnClickListener(view -> graph.getViewport().setScalable(!graph.getViewport().isScalable()));
        new GraphCreator().execute(ecgData);
    }

Full stack trace

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.holterapp, PID: 1773
    java.util.ConcurrentModificationException
        at java.util.ArrayList$Itr.next(ArrayList.java:860)
        at com.jjoe64.graphview.series.BaseSeries$1.next(BaseSeries.java:237)
        at com.jjoe64.graphview.series.BaseSeries$1.next(BaseSeries.java:187)
        at com.jjoe64.graphview.series.LineGraphSeries.draw(LineGraphSeries.java:263)
        at com.jjoe64.graphview.GraphView.drawGraphElements(GraphView.java:309)
        at com.jjoe64.graphview.GraphView.onDraw(GraphView.java:336)
        at android.view.View.draw(View.java:22350)
        at android.view.View.updateDisplayListIfDirty(View.java:21226)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4500)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4473)
        at android.view.View.updateDisplayListIfDirty(View.java:21186)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4500)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4473)
        at android.view.View.updateDisplayListIfDirty(View.java:21186)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4500)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4473)
        at android.view.View.updateDisplayListIfDirty(View.java:21186)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4500)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4473)
        at android.view.View.updateDisplayListIfDirty(View.java:21186)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4500)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4473)
        at android.view.View.updateDisplayListIfDirty(View.java:21186)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4500)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4473)
        at android.view.View.updateDisplayListIfDirty(View.java:21186)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4500)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4473)
        at android.view.View.updateDisplayListIfDirty(View.java:21186)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4500)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4473)
        at android.view.View.updateDisplayListIfDirty(View.java:21186)
        at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:559)
        at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:565)
        at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:642)
        at android.view.ViewRootImpl.draw(ViewRootImpl.java:4101)
        at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3828)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3099)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1952)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8171)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:972)
        at android.view.Choreographer.doCallbacks(Choreographer.java:796)
        at android.view.Choreographer.doFrame(Choreographer.java:731)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
0

There are 0 answers