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

Posted

技术标签:

【中文标题】这些在 UI 线程上运行代码的方法有啥区别?【英文标题】:What is the difference between these methods for running code on UI Thread?这些在 UI 线程上运行代码的方法有什么区别? 【发布时间】:2020-01-30 18:48:11 【问题描述】:

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

【问题讨论】:

***.com/questions/13974661/… 【参考方案1】:

android 中,一个线程可能有一个 Looper 或 MessageQueue。 Handler用于向线程的MessageQueue发送Message或post Runnable,必须始终与线程的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,则会抛出异常。

方法3

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

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

【讨论】:

完美详解!【参考方案2】:

方法 1 将始终有效。

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

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

【讨论】:

【参考方案3】:

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

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

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

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

【讨论】:

以上是关于这些在 UI 线程上运行代码的方法有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

并发、并行和异步方法有啥区别?

在 UI 线程上加载和创建 AsyncTask 有啥区别?

异步编程和多线程有啥区别?

线程池中的可运行与线程内和线程池中的可运行有啥区别

这些相同的网站有啥区别? [关闭]

Android 基础:在 UI 线程中运行代码