UI 线程上 运行 代码的这些方法有什么区别?

What is the difference between these methods for running code on UI Thread?

网络上发布了关于如何在 UI 线程上 运行 编码的不同方法。它们都完成相同的任务,但是,我真的很想知道这些方法之间的区别。

方法一:

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        // Code here will run in UI thread
    }
});

方法二:

new Handler().post(new Runnable() {
    @Override
    public void run() {
        // Code here will run in UI thread
    }
});

方法三:

 runOnUiThread(new Runnable() {
     @Override
     public void run() {
     // Code here will run in UI thread
     }
 });

所有方法都是这样工作的:

如果循环存在则方法 1 循环处理程序

方法 2 处理程序可以在所有活动中使用,如果不是私有的或不需要的话

方法 3 处理程序只能在当前 activity

方法一永远有效。

方法 2 仅在您已经在 UI 线程上时才有效 - 没有 Looper 参数的新 Handler 为当前线程创建一个 Handler(如果当前线程上没有 Looper 则失败).

方法 3 需要在 Activity 中完成或在 Activity 对象上调用,因为 runOnUiThread 是 Activity 的函数。但在引擎盖下它会做与 1 相同的事情(尽管可能保留一个处理程序以提高效率,而不是总是新建一个处理程序)。

在Android中,一个Thread可能有一个Looper或MessageQueue。 Handler用于向Thread的MessageQueue发送Message或postRunnable,必须始终与Thread的Looper或MessageQueue关联。

方法一

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        // Code here will run in UI thread
    }
});

打开应用程序时,Android创建一个新线程(称为主线程或UI线程),带有Looper和MessageQueue,该线程用于渲染UI和处理来自用户的输入事件。

以上代码是创建了一个Handler,关联了UI个线程的Looper,所以runnable会被排队到UI个线程的MessageQueue中,稍后执行。

方法二

new Handler().post(new Runnable() {
    @Override
    public void run() {
        // Code here will run in UI thread
    }
});

创建Handler并关联当前线程的Looper,有3种情况:

  • 如果这段代码在UI线程上执行,那么runnable会被排队到UI线程的MessageQueue中,稍后执行。
  • 如果这段代码是在后台线程执行的,如果这个线程有Looper,那么runnable会被排队到后台线程的MessageQueue中,稍后执行。
  • 如果这段代码是在后台线程执行的,而这个线程没有Looper,那么就会抛出异常

方法三

runOnUiThread(new Runnable() {
     @Override
     public void run() {
     // Code here will run in UI thread
     }
});

runOnUiThread只是Activity的一个实用方法,当你想在UI线程上执行一些代码时使用它。此方法背后的逻辑是如果当前线程是 UI 线程,则立即执行它,否则使用 Handler post 向 UI 线程的 MessageQueue 发送消息(如方法 1)。