runOnUiThread против Looper.getMainLooper (). сообщение в Android

99

Может ли кто-нибудь сказать мне, есть ли разница между использованием runOnUiThread () и Looper.getMainLooper (). Post () для выполнения задачи в потоке пользовательского интерфейса в Android?

Единственное, что я могу определить, так это то, что, поскольку runOnUiThread является нестатическим методом Activity, Looper.getMainLooper (). Post () более удобен, когда вам нужно закодировать что-то в классе, который не может видеть Activity (например, интерфейс).

Я не ищу обсуждения того, следует ли что-то выполнять в потоке пользовательского интерфейса, я понимаю, что некоторые вещи не могут, а многие вещи не должны, однако некоторые вещи (например, запуск AsyncTask) ДОЛЖНЫ выполняться из поток пользовательского интерфейса.

Спасибо,
Р.

Богатый
источник
6
Нет никакой разницы, за исключением того, что runOnUiThreadпроверит, является ли он уже потоком пользовательского интерфейса, и выполнит вашу задачу напрямую, вместо того, чтобы публиковать ее какMessage
zapl
1
Спасибо. Не могли бы вы превратить это в ответ, чтобы я мог его принять?
Rich
Кроме того, я уже написал некоторый код, чтобы проверить, выполняется ли что-то в потоке пользовательского интерфейса, поэтому было бы очень просто включить его вручную.
Rich

Ответы:

192

Следующее ведет себя так же при вызове из фоновых потоков:

  • с помощью Looper.getMainLooper()

    Runnable task = getTask();
    new Handler(Looper.getMainLooper()).post(task);
    
  • с помощью Activity#runOnUiThread()

    Runnable task = getTask();
    runOnUiThread(task);
    

Единственная разница в том, когда вы делаете это из потока пользовательского интерфейса, поскольку

public final void runOnUiThread(Runnable action) {
    if (Thread.currentThread() != mUiThread) {
        mHandler.post(action);
    } else {
        action.run();
    }
}

проверит, является ли текущий поток уже потоком пользовательского интерфейса, а затем выполнит его напрямую. Публикация его как сообщения задержит выполнение до тех пор, пока вы не вернетесь из текущего метода UI-потока.

Существует также третий способ выполнить a Runnableв потоке пользовательского интерфейса View#post(Runnable)- он всегда будет отправлять сообщение, даже если вызывается из потока пользовательского интерфейса. Это полезно, поскольку это гарантирует, что Viewобъект был правильно построен и имеет макет до выполнения кода.

запл
источник