Как отобразить полученные данные из базы данных Firebase в android - PullRequest
0 голосов
/ 20 апреля 2020

Я получаю данные из базы данных Firebase Realtime. У меня нет проблем с получением данных. Но когда мне надоело записывать полученные данные в графическое представление. После добавления нескольких точек программа вылетает со следующей ошибкой:

ошибка

E/AndroidRuntime: FATAL EXCEPTION: Thread-10
     Process: com.example.firebase, PID: 6687
     java.util.ConcurrentModificationException
         at java.util.ArrayList$Itr.next(ArrayList.java:860)
         at com.jjoe64.graphview.series.BaseSeries.appendData(BaseSeries.java:445)
         at com.jjoe64.graphview.series.LineGraphSeries.appendData(LineGraphSeries.java:646)
         at com.jjoe64.graphview.series.BaseSeries.appendData(BaseSeries.java:464)
         at com.example.firebase.MainActivity.AddPointChart(MainActivity.java:27)
         at com.example.firebase.MainActivity.access$000(MainActivity.java:24)
         at com.example.firebase.MainActivity$MyThread.run(MainActivity.java:38)

Вот мой код:

 private void AddPointChart(float Value){
            x++;
            series.appendData(new DataPoint(x,Value),true,1500);
            graph.addSeries(series);
    }

    class MyThread extends Thread{
        public void run(){
            float Value;
            while(true)
            {
                if (!kuyruk.isEmpty()){
                    Value= Float.parseFloat(String.valueOf(kuyruk.poll()));
                    AddPointChart(Value);
                }
            }
        }
    }
    TextView s_indexNo,s_Value;
    Button btn;
    DatabaseReference reff;
    GraphView graph;
    LineGraphSeries series;
    FirebaseDatabase database;

    public Queue kuyruk=new LinkedList();
    int x=0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        s_indexNo=(TextView)findViewById(R.id.txtindex);
        s_Value=(TextView)findViewById(R.id.txtvalue);
        btn=(Button)findViewById(R.id.button2);
        graph=(GraphView)findViewById(R.id.graph);
        series=new LineGraphSeries();
        graph.addSeries(series);
        database = FirebaseDatabase.getInstance();
        reff=database.getReference("ABC123");

        btn.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view){
                reff= FirebaseDatabase.getInstance().getReference().child("ABC123");
                reff.addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                        MyThread t=new MyThread();
                        t.start();
                        float Value=Float.parseFloat(dataSnapshot.child("Value").getValue().toString());
                        kuyruk.offer(Value);
                    }
                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) {
                    }
                });
            }
        });
    }

1 Ответ

0 голосов
/ 20 апреля 2020

Как только метод onDataChange запускается снова, вы запускаете второй поток, который обновляет GraphView. Это приводит к тому, что два потока одновременно записывают в одно и то же графическое представление, что приводит к ошибке.

Чтобы исправить это, следует сохранить ссылку на поток в действии:

MyThread graphUpdater;

Затем переместите создание потока из ValueEventListener, например

btn.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(View view) {
        // check if thread is already created
        if (graphUpdater != null) {
            // if already running, ignore button press
            // you could stop your thread here to stop the graph plotting
            // if you want
            return;
        }
        reff= FirebaseDatabase.getInstance().getReference().child("ABC123");
        reff.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                float Value=Float.parseFloat(dataSnapshot.child("Value").getValue().toString());
                kuyruk.offer(Value);
            }
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }
        });
        // create one thread
        graphUpdater = new MyThread();
        graphUpdater.start();
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...