void function(){
//somePreExecutionCode
new Handler().post(new Runnable(){
@Override
public void run(){
//someCode
}
});
}
似乎它没有阻止UI,因此调用function()的按钮在someCode完成之前不会卡在点击的位置。 但是如果somePreExecutionCode启动了progressBar,那么当someCode完成时,progressBar会在完全相同的时刻显示。 我知道,有AsyncTasks,但还有其他可能吗?
之间的区别是什么?
new Handler().post
和
View.post
答案 0 :(得分:8)
创建Android应用程序时,系统会创建一个主要的执行线程。此线程称为UI线程,所有与UI相关的操作都发生在此线程上,以避免同步问题。
在此线程上创建Looper实例,该实例具有MessageQueue数据结构。 Looper将处于无限循环中,等待阅读Message上发布的Runnable / MessageQueue个实例。要将Message7 / Runnable添加到MessageQueue,请使用Handler。
当您创建Handler实例时,它将与当前执行线程以及在该特定线程上创建的Looper实例相关联。
因此,当您通过处理程序发布消息时,消息将添加到MessageQueue中,该消息将由Looper以FIFO顺序读取,并将传递给目标。
new Handler()。post()和View.post有点不同。
答案 1 :(得分:4)
简单地说,有 Looper线程,例如 UI线程。这样的线程有自己的Looper,它为线程运行一个消息循环。
此类线程通常有一个Handler,用于处理其Looper
的消息 - 覆盖public void handleMessage(Message msg)
或执行Runnable
,该消息已发布到其looper的消息中队列中。
当您在 UI线程的上下文中创建Handler
时(就像您在代码中所做的那样),它会与 UI线程的 looper相关联,因此您的\\someCode
在 UI线程上运行。
我想,在您的用例中new Handler().post(Runnable)
和View:post(Runnable)
大致相同,因为它们都会在 UI线程消息队列中添加Runnable
。
但他们不一样。
View:post(Runnable)
会将Runnable
添加到 UI线程 looper的消息队列中; Handler:post(Runnable)
会将Runnable
添加到其关联的线程循环播放器消息队列我的解释非常直观,如果我错了,请纠正我。
答案 2 :(得分:0)
根据the Android View's documentation:
Runnable将在用户界面线程上运行
根据the Android Handler's documentation:
Runnable将在此处理程序所附加的线程上运行
所以,在Handler的情况下,你可以在你想要的任何线程中创建它,它是一种锚,它将执行你在创建它的线程中提供的Runnable。
在View.post中,您将始终在uI线程中执行Runnable。