Search code examples
javaandroidchronometer

App Crash on Arrayupdate within Ticklistener


im working through my first app right now and i have a problem concerning an update of an Arraylist object.

This is the code:

package com.example.stopwatchmulti;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.ListView;
import android.widget.TextView;

import java.util.ArrayList;

public class Main2Activity extends AppCompatActivity {

    //Define Variables and Arrays

    String ergebnis;
    String stopTime;
    int anzahl;
    int hours;
    int minutes;
    int seconds;
    Chronometer chronometer;
    long pauseOffset;
    boolean running;
    int arrayelements = anzahl - 1;
    long timeElapsed;


    ListView customListview;
    ArrayList<UserIDs> userList;
    ArrayList<String> stoppedTime;
    CustomListview adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        ergebnis = getIntent().getExtras().getString("Ergebnis");

        anzahl = Integer.parseInt(ergebnis);

        chronometer = findViewById(R.id.chronometer);

        customListview = (ListView) findViewById(R.id.customListview);

        userList = new ArrayList<>();

        // Add Lines in favour of UserChoice in First activity

        for (int i = 1; i <= anzahl; i++) {

            UserIDs user = new UserIDs(String.valueOf(i), "Chronometer" + String.valueOf(i), stopTime);
            userList.add(user);

        }

        stopTime = String.valueOf(hours)+":"+String.valueOf(minutes)+":"+String.valueOf(seconds);

        // Run Custom ArrayAdapter
        adapter = new CustomListview(this, R.layout.usertableobjects, userList);
        customListview.setAdapter(adapter);

        }

        public void startChronometer(View v) {
            if (!running) {
                chronometer.setBase(SystemClock.elapsedRealtime());
                chronometer.start();
                running = true;
                new Thread(new updateStoptime()).start();

            }
        }

    public void pauseChronometer(View v) {
            if (running) {
                chronometer.stop();
                running = false;
            }
        }

        public void resetChronometer(View v) {
            chronometer.setBase(SystemClock.elapsedRealtime());
        }

    class updateStoptime implements Runnable {

        @Override
        public void run() {
            chronometer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
                @Override
                public void onChronometerTick(Chronometer chronometer) {

                    timeElapsed = SystemClock.elapsedRealtime() - chronometer.getBase();

                    hours   = (int) (timeElapsed / 3600000);
                    minutes = (int) (timeElapsed - hours * 3600000 / 6000);
                    seconds = (int) (timeElapsed - hours * 3600000 - minutes * 60000) / 1000;

                    stopTime = String.valueOf(hours)+":"+String.valueOf(minutes)+":"+String.valueOf(seconds);

                    Log.i("Zeit:", String.valueOf(stopTime));

                }
            });

            while(running == true){

                for (int i = 1; i <= anzahl; i++) {

                    userList.get(arrayelements).setUserTime(stopTime);
                    Log.i("LoopNr:", String.valueOf(i));
                }
            }
        }
    }
}

The update of the arraylist in the while loop is the reason why the app is crashing when the user clicks the button. If I just loop through and print the number of the loop in the logs, everything is ok.

Is it too much dada? How can I fix it?

PS. Basically I just need the actual countdowntime, when the user clicks the button and then update the listview with the updated array. So if there's a better and smarter way to achieve this instead of using a while loop, i would appreciate a hint.

Thx in advance


Solution

  • Quick correction:

    
    // Here anzahl is not initialized and is being referred to in the next line.
    // Please initialize anzahl first;
       int anzahl;
       int arrayelements = anzahl - 1;
    

    Then, change your while loop to something like this.

       while(running == true){
    
          for (int i = 1; i <= anzahl; i++) {
    
             /* here, just call "i -1". this is basically equal to "arrayelements"
                which is not properly referenced up in your code.*/
    
             userList.get(i - 1).setUserTime(stopTime);
             Log.i("LoopNr:", String.valueOf(i));
          }
        }