-1

关于如何在 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
     }
 });
4

3 回答 3

1

方法 1 将始终有效。

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

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

于 2019-10-01T13:22:18.080 回答
1

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

方法一

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

当打开一个应用程序时,Android 会创建一个带有 Looper 和 MessageQueue 的新线程(称为主线程或 UI 线程),该线程用于渲染 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向UI线程的MessageQueue发送消息(如方法1)。

于 2019-10-02T04:13:44.797 回答
0

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

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

如果不是私有的或想要的,方法 2 处理程序可以在所有活动中工作

方法 3 处理程序只能在当前活动中工作

于 2019-10-01T13:12:55.933 回答