Ich möchte einen einfachen Timer in Android erstellen, der jede Sekunde ein TextView aktualisiert. Es zählt einfach Sekunden wie in Minesweeper.
Das Problem ist, wenn ich das tvTime.setText (...) ignoriere (mache es //tvTime.setText (...), in LogCat wird jede Sekunde die folgende Nummer gedruckt ...), aber wenn ich das einstellen möchte Nummer zu einem TextView (erstellt in einem anderen Thread) stürzt das Programm ab.
Hat jemand eine Idee, wie man das einfach lösen kann?
Hier ist der Code (die Methode wird beim Start aufgerufen):
private void startTimerThread() {
Thread th = new Thread(new Runnable() {
private long startTime = System.currentTimeMillis();
public void run() {
while (gameState == GameState.Playing) {
System.out.println((System.currentTimeMillis() - this.startTime) / 1000);
tvTime.setText("" + ((System.currentTimeMillis() - this.startTime) / 1000));
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
th.start();
}
BEARBEITEN:
Schließlich habe ich es bekommen ... Hier ist die Lösung für diejenigen, die sich dafür interessieren.
private void startTimerThread() {
Thread th = new Thread(new Runnable() {
private long startTime = System.currentTimeMillis();
public void run() {
while (gameState == GameState.Playing) {
runOnUiThread(new Runnable() {
@Override
public void run() {
tvTime.setText(""+((System.currentTimeMillis()-startTime)/1000));
}
});
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
th.start();
}
Das UserInterface kann nur vom UI-Thread aktualisiert werden. Sie benötigen einen Handler , um im UI-Thread zu posten:
private void startTimerThread() {
Handler handler = new Handler();
Runnable runnable = new Runnable() {
private long startTime = System.currentTimeMillis();
public void run() {
while (gameState == GameState.Playing) {
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable(){
public void run() {
tvTime.setText("" + ((System.currentTimeMillis() - this.startTime) / 1000));
}
});
}
}
};
new Thread(runnable).start();
}
Alternativ können Sie dies auch einfach in Ihrem Thread tun, wenn Sie ein Oberflächenelement aktualisieren möchten:
runOnUiThread(new Runnable() {
public void run() {
// Update UI elements
}
});
Verwenden Sie als Option runOnUiThread () , um die Eigenschaften der Ansichten im Hauptthread zu ändern.
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText("Stackoverflow is cool!");
}
});
Sie können nicht auf Benutzeroberflächenelemente von Threads außerhalb der Benutzeroberfläche zugreifen. Versuchen Sie, den Aufruf von setText(...)
mit einer anderen Runnable
zu umgeben, und schauen Sie sich dann die Methode View.post(Runnable)
an.