Що таке Android UiThread (потік інтерфейсу користувача)


81

Хтось може пояснити мені, що саме являє собою потік інтерфейсу користувача? На developer.android.com написано про функцію runOnUiThread

public final void runOnUiThread (Runnable action)

Оскільки: API Level 1 Запускає вказану дію над потоком інтерфейсу користувача. Якщо поточним потоком є ​​потік інтерфейсу користувача, тоді дія виконується негайно. Якщо поточний потік не є потоком інтерфейсу користувача, дія розміщується в черзі подій потоку інтерфейсу користувача.

Чи означає потік інтерфейсу користувача, що він буде запускатися кожного разу, коли дія відсувається на задній план якоюсь користувацькою діяльністю, як вхідний дзвінок, затемнення екрану тощо? Якщо ні, то що саме включає потік інтерфейсу користувача?

Дякую

Відповіді:


144

UIThread - основний потік виконання для вашої програми. Тут виконується більша частина коду вашої програми. Усі компоненти вашої програми (Activity, Services, ContentProviders, BroadcastReceivers) створюються в цьому потоці, і будь-які системні виклики цих компонентів виконуються в цьому потоці.

Наприклад, припустимо, що ваша програма - це один клас Activity. Тоді всі методи життєвого циклу та більшість вашого коду обробки подій запускаються в цьому UIThread. Ці методи , як onCreate, onPause, onDestroy, onClickі т.д. Крім того, це де всі оновлення до UI зроблені. Все, що призводить до оновлення або зміни інтерфейсу користувача, МОЖЕ відбуватися в потоці інтерфейсу користувача.

Для отримання додаткової інформації про процеси та потоки вашої програми натисніть тут.

Коли ви явно створюєте новий потік для роботи у фоновому режимі, цей код не запускається на UIThread. Отже, що трапиться, якщо цей фоновий потік повинен зробити щось, що змінює інтерфейс? Для цього і runOnUiThreadє. Насправді ви повинні використовувати обробник (див. Посилання нижче для отримання додаткової інформації про це). Він надає цим фоновим потокам можливість виконувати код, який може змінювати інтерфейс користувача. Вони роблять це, поміщаючи код, що модифікує інтерфейс, в об’єкт Runnable і передаючи його методу runOnUiThread.

Для отримання додаткової інформації про нерест робочих потоків та оновлення інтерфейсу з них натисніть тут

Я особисто використовую цей runOnUiThreadметод лише в своїх тестах на приладобудування. Оскільки тестовий код не виконується в UIThread, вам потрібно використовувати цей метод для запуску коду, який змінює інтерфейс користувача. Отже, я використовую його для введення кліків та ключових подій у мою програму. Потім я можу перевірити стан програми, щоб переконатися, що сталося правильно.

Для отримання додаткової інформації про тестування та запуск коду на UIThread натисніть тут


3
Чудове пояснення, спеціально посилання на основи додатків, яке обов’язково потрібно прочитати для всіх початківців, таких як я :)
Java Student

1
Чи не варто в більшості випадків використовувати AsyncTaskзамість цього runOnUiThread?
JDJ

5
@JDJ 2 техніки мають різні цілі: AsyncTaskзмусять вас вимикати основний потік на задній план; runOnUiThread()перенесе вас до основного потоку з фонового режиму. Отже, це залежить від того, що ви намагаєтесь досягти.
Richard Le Mesurier

10

Якщо ви виконуєте код блокування (наприклад, Http-запит) в окремій темі, розгляньте можливість використання AsyncTask . Його doInBackground-метод працює на окремій нитці. AsyncTaskнадає методи onProgressUpdateі onPostExecuteякі гарантовано працюють на потоці призначеного для користувача інтерфейсу .

Якщо вам потрібні оновлення графічного інтерфейсу (наприклад, за допомогою індикатора прогресу), зателефонуйте publishProgressвсередину doInBackground. Це призводить до подальшого виклику, onPublishProgressякий також гарантовано працює в потоці інтерфейсу користувача .

onPostExecuteавтоматично викликається після doInBackgroundповернення.


5

Усі креслення інтерфейсу користувача тощо відбуваються в окремому потоці. Його називають UIThread. Якщо ви хочете внести будь-які зміни в інтерфейс користувача, ви повинні скористатися переконайтеся, що це відбувається в контексті UIThread. Найпростіший спосіб зробити це - скористатисяrunOnUiThread


Чи можете ви підготувати структури даних віджетів (наприклад, надути макет) у потоці, що не є інтерфейсом, а потім намалювати їх пізніше в потоці інтерфейсу?
SMBiggs

ніколи не пробував цього, але технічно це повинно бути можливим, оскільки інфляція просто створює структуру даних. Його частина, коли ви приєднуєтеся до діяльності тощо, це коли вам потрібно це зробити в контексті UIThread.
the100rabh
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.