Обновление Android TextView в потоке и Runnable
Я хочу сделать простой таймер в Android, который обновляет TextView каждую секунду. Он просто считает секунды, как в Минере.
проблема в том, что я игнорирую tvTime.помощью setText(...) (make it / / tvTime.помощью setText(...), в LogCat будет печататься следующий номер каждую секунду. Но когда я хочу установить это число в TextView (созданный в другом потоке), программа аварийно завершает работу.
есть ли у кого-нибудь идея, как это легко решить?
здесь код (метод вызывается при запуске):
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();
}
EDIT:
наконец, я понял. Вот решение, для тех, кто интересуется.
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();
}
4 ответов
UserInterface может быть обновлен только потоком пользовательского интерфейса. Вам нужно проводник, чтобы отправить сообщение в UI-потоке:
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();
}
кроме того, вы также можете просто сделать это в своем потоке, когда вы хотите обновить элемент UI:
runOnUiThread(new Runnable() {
public void run() {
// Update UI elements
}
});
вы не можете получить доступ к элементам пользовательского интерфейса из не-UI потоков. Попробуйте окружить вызов setText(...)
с другой Runnable
а затем посмотрите в View.post(Runnable)
метод.
в качестве опции используйте runOnUiThread() для изменения свойств de views в основном потоке.
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText("Stackoverflow is cool!");
}
});