android - 在主线程中创建的处理程序就像在另一个线程上一样
问题描述
正如谷歌所说:
Handler 允许您发送和处理与线程的 MessageQueue 关联的 Message 和 Runnable 对象。每个 Handler 实例都与单个线程和该线程的消息队列相关联。当您创建一个新的处理程序时,它会绑定到创建它的线程的线程/消息队列——从那时起,它会将消息和可运行对象传递到该消息队列并在它们从消息中出来时执行它们队列。
我希望当我在主线程(UI线程)中创建一个处理程序时,它会附加到这个线程,所以它会导致冻结ui直到它的任务结束。但是在测试中,这不会发生,它就像在后台线程上一样,并且并行执行他的任务。我曾经这样创建句柄:
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable runnable = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 35000; i++) {
log.i(TAG,"log in Handler:"+i);
}}
};
mainHandler.post(runnable);
log.i(TAG,"log outSide");
在 mainActivity 中(所以句柄应该绑定到主线程)。那么这有什么问题,还是我以错误的方式创建处理程序?
有些朋友注意到这doSomthing()
还不够复杂,但是为什么我们在“log in Handler:”之前看到“log outSide”,如果他们在同一个线程中。
解决方案
实际上,它正在按您的预期工作,您的处理程序当前与您的主线程相关联,因为它是在其中创建的,并且您的任务也在同一线程上运行。尝试在 for 循环中添加Thread.sleep(1000)方法,然后您将在 UI 中看到冻结。您当前的代码以 O(1) 的复杂度运行,因为您的 N 是恒定的,并且您的手机有足够的能力在几分之一秒内运行它,这就是为什么您在测试期间没有观察到 UI 中出现任何冻结的原因。
推荐阅读
- tensorflow - 在 Keras 中的每一步之后更改学习率
- azure - Azure FrontDoor 的 terraform 模块中的嵌套循环
- javascript - 如何在反应js中固定位置的div动画?
- typescript - 字符串上的打字稿条件类型包括
- python - 在python中导入nim seq
- java - 导入类/包放置在另一个相同/更高层次的包中
- php - 如何让 sql 排名查询工作以查找特定 id 的排名
- git - 是否可以从 master 创建的分支中获取更改作为本地更改返回到 master?
- pandas - pd.isnull().sum() 的 Vaex 命令是什么?
- javascript - 引导日期选择器始终在顶部打开