TextView bei start eines Threads ändern

A

Android_DEV

Ambitioniertes Mitglied
1
Hallo,
bei meinem Intervall CountDownTimer Projekt nutze ich sobald die 'normale' Zeit abgelaufen ist eine onFinish Methode in der ein sleep Thread ist.
Dieser Thread dauert dann z.B. 10 Sekunden und dann läuft das Programm von vorne los. Wenn der Threat anfängt soll im TextView nicht mehr "00:00:00" stehen sondern "Warte".

Meine Idee:

Code:
public void onFinish() { 

 textViewTime.setText("wait"); 
                    try {
                  Thread.sleep(5000);
 } catch (InterruptedException e) {                 
           e.printStackTrace();             }             
           this.start();         }


Sobald die onFinish Methode aufgerufen wird, ändert der Text sich mit.
Das funktioniert nur leider nicht.

Hier der komplette code:

Code:
public class MainActivity extends ActionBarActivity {



    Button btnStart, btnStop;
    TextView textViewTime;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnStart = (Button)findViewById(R.id.btnStart);
        btnStop = (Button)findViewById(R.id.btnStop);
        textViewTime = (TextView)findViewById(R.id.textViewTime);
        textViewTime.setText("00:00:00");



        final CounterClass timer = new CounterClass(10000,1000);
        btnStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                timer.start();

            }
        });
        btnStop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                timer.cancel();
            }
        });
        
    }
    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
    @SuppressLint("NewApi")
    public class CounterClass extends CountDownTimer {
        public CounterClass(long millisInFuture, long countDownInterval) {
            super(millisInFuture, countDownInterval);
        }



        @Override
        public void onFinish() {
            textViewTime = (TextView)findViewById(R.id.textViewTime);
            textViewTime.setText("wait");

            try {
                Thread.sleep(5000);

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            this.start();
        }
        @SuppressLint("NewApi")
        @TargetApi(Build.VERSION_CODES.GINGERBREAD)
        @Override
        public void onTick(long millisUntilFinished) {

            long millis = millisUntilFinished;
            String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis),
                    TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
                    TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
            System.out.println(hms);
            textViewTime.setText(hms);
        }
    }
}

Danke im voraus :) :thumbsup:
 
Du befindest dich in onFinish auf dem main thread und blockierst diesen -> absolutes noGo.

Wenn du das so machen willst, dann poste einen neuen Thread in onFinish und lass diesen warten.
Code:
new Thread() { 
   try catch block
   CounterClass.this.start();
}.start();
jetzt ist wichtig, dass du deinen timer in onPause abbrichst, falls du ihn nicht beendest. Sonst gibbet memory leak.

Und:
Das findViewById in onFinish ist überflüssig, weil du das bereits in der onCreate drin hast.
 
Verstehe ich nicht ganz. Wenn ich z.B. das textViewTime.setText("wait"); ohne den thread in die onFinish setze läuft die Zeit wie gewünscht ab und wenn sie rum ist verändert sich auf die TextView. Ich will ja, dass die TextView sich ändert, wenn der normale Timer abgelaufen ist, also kurz bevor der thread anfängt. Bei meiner Version bleibt die TextView unverändert.
 
Da du aber das Textfeld dort setzen kannst bist du im Main bzw UI Thread unterwegs.
Du sagst dem Textfeld es soll den Text setzen und direkt danach blockierst du den Thread aber.

das setzen vom Text passiert nicht sofort, sondern braucht auch Zeit, wenn auch nicht viel, da du direkt danach aber Thread.sleep machst und das den Thread sofort anhält wird auch dein Text nicht mehr geändert.*

Aber wie schon geschrieben.. Thread.sleep im Main/UI Thread ist verboten. Sollte man niemals machen.



*Funktioniert im Detail nicht ganz so, aber es beschreibt das Grundproblem.
 
Und wenn ich anstatt dem thread einfach in der onFinish methode einen neuen timer starte, welcher dann 10 Sekunden dauert? Würde ich da eine komplett neue counterclass benötigen ?

Der ursprüngliche Beitrag von 20:53 Uhr wurde um 21:15 Uhr ergänzt:

Das funktioniert besser :D

Code:
public class MainActivity extends ActionBarActivity {
    CountDownTimer counter;





    Button btnStart, btnStop;
    TextView textViewTime;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnStart = (Button)findViewById(R.id.btnStart);
        btnStop = (Button)findViewById(R.id.btnStop);
        textViewTime = (TextView)findViewById(R.id.textViewTime);
        textViewTime.setText("00:00:00");
        counter=new CountDownTimer(30000, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                long millis = millisUntilFinished;
                String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis),
                        TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
                        TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
                System.out.println(hms);
                textViewTime.setText(hms);

            }

            @Override
            public void onFinish() {

       counter.start();
            }
        };


        final CounterClass timer = new CounterClass(10000,1000);

        btnStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                timer.start();

            }
        });
        btnStop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                timer.cancel();
            }
        });

    }
    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
    @SuppressLint("NewApi")
    public class CounterClass extends CountDownTimer {
        public CounterClass(long millisInFuture, long countDownInterval) {
            super(millisInFuture, countDownInterval);
        }





            @Override
        public void onFinish() {
                counter.start();



            }
        @SuppressLint("NewApi")
        @TargetApi(Build.VERSION_CODES.GINGERBREAD)
        @Override
        public void onTick(long millisUntilFinished) {

            textViewTime.setText("seconds remaining: " + millisUntilFinished / 1000);


            long millis = millisUntilFinished;
            String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis),
                    TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
                    TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
            System.out.println(hms);
            textViewTime.setText(hms);
        }
    }
}
 
Wieso lagerst du die Klasse nicht aus und implementierst ein Runnable?

Code:
class CountDownTimerThread implements Runnable {

protected OnFinishListener onFinishListener = null;
protected TextView textViewTime = null;
protected CountDownTimer count = null;

public CountDownTimerThread (TextView textViewTime) {
  this.textViewTime = textViewTime;
}

public void setOnFinishListener (OnFinishListener onFinishListener) {
  this.onFinishListener = onFinishListener;
}

@Override
public void run () {
  this.counter = new CountDownTimer (30000, 1000) {
    //...
    this.textViewTime.setText(hms);
  }
  //Zählen

  //Wenn fertig, onFinishListener aufrufen
  if (this.onFinishListener != null) {
    this.onFinishListener.onFinish(this);
  }
}

public interface OnFinishListener {
  public void onFinish(CountDownTimerThread thread);
}

}

MainActivity.java:
Code:
public class MainActivity extends ActionBarActivity {

protected CountDownTimerThread thread = null;
protected Button btnStart = null;
protected Button btnStop = null;
protected TextView textViewTime = null;

@Override
public void onCreate (Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  this.setContentView(R.layout.activity_main);

  //Buttons initialisieren
  this.btnStart = (Button) this.findViewById(R.id.btnStart);
  this.btnStop = (Button) this.findViewById(R.id.btnStop);

  //TextView initialisieren
  this.textViewTime = (TextView) this.findViewById(R.id.textViewTime);

  this.thread = new CountDownTimerThread(this.textViewTime);
}

}
 

Ähnliche Themen

D
Antworten
14
Aufrufe
1.704
chrs267
chrs267
D
Antworten
17
Aufrufe
408
datNeMo
D
M
Antworten
3
Aufrufe
166
moin
M
Zurück
Oben Unten