Я смущен тем, как работает система Android, особенно когда она обновляет иерархию представлений. Мы все знаем, что мы не должны обновлять какой-либо вид из любого потока, кроме потока пользовательского интерфейса (Main). И даже система Android выбрасывает исключение, когда мы пытаемся это сделать. На днях я пытался реализовать пользовательский прогресс, показывающий представление в моем приложении. Поэтому я начал с использования стандартных потоков Java и компилятора обработчика.Обновление просмотров из не-пользовательских потоков
Что меня удивило, так как я смог обновить TextView из фонового потока.
new Thread(new Runnable() {
@Override
public void run() {
mTextView.setText("I am " + Thread.currentThread().getName());
}
}).start();
После этого я попробовал обновить другие виды, которые работали довольно хорошо. Поэтому я попытался поставить вызов сна в фоновом потоке.
new Thread(new Runnable() {
@Override
public void run() {
mTextView.setText("Thread : before sleep");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mTextView.setText("Thread : after sleep");
}
}).start();
И он выходит из строя, как ожидается, говоря
android.view.ViewRootImpl $ CalledFromWrongThreadException: только оригинальный поток, который создал иерархию вида может коснуться его точки зрения.
Затем я попытался положить SetText() вызывает в петлю на 100, 1000 раз до и после вызова сна(). Конечно, приложение падает каждый раз, но я смог увидеть текст «Перед сном» в своем текстовом виде.
Так что мой вопрос когда же система обнаружит, что некоторые не-UI поток пытается обновить представление. И Почему он не работает, когда нет вызова sleep() в не-UI-потоке?
Просто используйте android.os.Handler - он всегда будет запускать свою runnable на UI-thread. – Dogcat
когда? см. 'android/view/ViewRootImpl.java' имя метода' checkThread' – pskink
@Dogcat: Я знаю о обработчике. Но мой вопрос в том, почему в первом случае не происходит сбоев системы? – apersiankite