Как известно, в Android обращаться к вью элементам можно только из того потока, в котором они были созданы. То есть только из UI (он же main) Thread. Но как видно из примера ниже, видимо есть какие-то исключения (либо я что-то не так понимаю):
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText et = (EditText) findViewById(R.id.et);
String name = currentThread().getName();
long id = Thread.currentThread().getId();
Log.i("THREAD", String.format(Locale.getDefault(),
"Outside runnable. Thread name = %s, threadId = %d", name, id));
// Создаём новый поток, запускаем его и изменяем UI
new Thread(new Runnable() {
@Override
public void run() {
String name = currentThread().getName();
long id = Thread.currentThread().getId();
Log.i("THREAD", String.format(Locale.getDefault(),
"Inside runnable. Thread name = %s, threadId = %d", name, id));
et.setText("From background");
}
}).start();
// Создаём новый поток, запускаем его и изменяем UI при клике на кнопку
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
String name = currentThread().getName();
long id = Thread.currentThread().getId();
Log.i("THREAD", String.format(Locale.getDefault(),
"Inside runnable with click. Thread name = %s, threadId = %d", name, id));
et.setText("From background with click");
}
}).start();
}
});
Имеется поле EditText
, в которое мы пытаеся установить новый текст из бекграунд потока. В первом случае поток создаётся и запускается в методе onCreate
. Во втором, поток создаётся и запускается при клике на кнопке.
Я ожидаю, что получу исключение android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
в первом же случае. Но этого не происходит и текст в поле корректно изменяется.
Но во втором случае, при запуске потока по клике, данное исключение ожидаемо выбрасывается.
Для уверенности, логирую имена и id потоков, в которых выполняются действия:
I/THREAD: Outside runnable. Thread name = main, threadId = 1
I/THREAD: Inside runnable. Thread name = Thread-64100, threadId = 64100
// Текст изменился
// Клик по кнопке
I/THREAD: Inside runnable with click. Thread name = Thread-64105, threadId = 64105
// Exception
android.view.ViewRootImpl$CalledFromWrongThreadException:
Only the original thread that created a view hierarchy can touch its views.
Кто нибудь может объяснить, почему мы не получаем исключение в первом случае? Чем он отличается от второго? Это нюансы работы с потоками в Java или особенности Android фреймворка?
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Как в коллекции, например, list реализовать механизм сортировки элементов, чтобы удалились те элементы, что делятся на 2 и 3
Как из вложенного класса правильно обратится к объекту внешнего класса?
В погодном приложении выдает ошибку NullPointerException на строчке: mWeatherLayoutsetVisibility(View