调用 Handler 时是不是需要调用 Looper.prepare()
Posted
技术标签:
【中文标题】调用 Handler 时是不是需要调用 Looper.prepare()【英文标题】:Do we need invoking Looper.prepare() when invoking Handler调用 Handler 时是否需要调用 Looper.prepare() 【发布时间】:2016-11-09 05:45:59 【问题描述】:我需要了解 Looper。 Looper 将咨询适当的 handler 来发送和处理与线程的 MessageQueue 关联的 Message 和 Runnable 对象。
默认情况下,线程没有与之关联的消息循环,因此也没有 Looper。要为某个线程创建 Looper 并专用于该线程以串行方式处理来自消息循环的消息,您可以使用 Looper 类。
以下是我没有显式调用 Looper 的代码
Thread background2 = new Thread(new Runnable()
@Override
public void run()
for ( int i = 0; i < 5; i++)
final int v =i;
try Thread.sleep(1000);
handler.post(new Runnable()
@Override
public void run()
txt.setText(txt.getText() + "Thread 2 current i : " + String.valueOf(v) +System.getProperty("line.separator"));
);
catch (Exception e)
Log.v("Error", e.toString());
);
是不是表示task/runnable没有放入队列?上面的代码和这个有什么区别
Thread background3 = new Thread(new Runnable()
@Override
public void run()
Looper.prepare();
for ( int i = 0; i < 5; i++)
final int v =i;
try Thread.sleep(1000);
handler.post(new Runnable()
@Override
public void run()
txt.setText(txt.getText()+ "Thread 3 set : " + String.valueOf(v) +System.getProperty("line.separator"));
);
catch (Exception e)
Log.v("Error", e.toString());
Looper.loop();
);
他们都访问一个相同的处理程序。它们都工作正常。
【问题讨论】:
一个Thread
不需要Looper
来发布到另一个Thread
的Handler
,如果这就是你要问的。您的示例中的 Handler
s 用于其他 Thread
s,无论您在哪个 Thread
s 上创建它们。
你好,我现在很困惑,所以我的第二个例子有什么区别,我明确地调用 Looper.prepare(),但没有它,它仍然有效
为Thread
创建一个Looper
意味着其他 Thread
s 可以向其发帖。您示例中的 Looper
并没有真正做任何事情,因为您没有向在那里创建的 Handler
发布任何内容,这就是您看不到差异的原因。
迈克,that other Threads can post to it
在这种情况下是什么?你能把它作为答案吗,
嗯,这里有很多答案已经涵盖了这一点,所以我宁愿找到一个重复的答案而不是发布一个重复的答案。无论如何,在您的第二个示例中,由于您在那个Thread
中开始一个Looper
,您可以为那个Looper
创建一个Handler
,将它传递给另一个Thread
,然后传递给另一个Thread
可以发布到它。您的示例Thread
s 将Runnable
s 发布到为Handler
s 创建的任何其他Thread
。他们不会将它们发布给自己。
【参考方案1】:
为Thread
创建Looper
意味着您正在设置该Thread
以接收来自其他Thread
s 的消息。您的两个示例的行为完全相同,因为在第二个示例中您没有向Thread
发送任何内容。也就是说,background3
的 Looper
并没有真正被使用。
在这两个示例中,您将Runnable
发布到为主要Thread
的Looper
创建的Handler
。您不是为 background2
等创建 Handler
。那个Handler
属于主Thread
和它的Looper
,你发布到它的任何东西都将被放入主队列,并在主Thread
上运行。
您的示例中唯一的区别是第二个Thread
有一个Looper
,如果您愿意,您可以 发布到它。为此,您将创建另一个属于background3
的Looper
的Handler
,然后发布到该Handler
。不过,您并没有这样做,所以第二个 Thread
只是继续运行,不做任何其他事情。
Thread
不需要Looper
来简单地发布到另一个Thread
的处理程序,这就是您的示例所做的一切。另一个Thread
——在这种情况下是主要的Thread
——已经准备好并开始了它的Looper
。您只是向它发送Runnable
s,您不需要自己的Looper
来执行此操作。
【讨论】:
如果我没有充分解释任何事情,请让我知道。 非常感谢 Mike 我知道了。您在评论中发布的其他帖子解释说 Looper 作为一种经理线程过于笼统。但你的回答很清楚。以上是关于调用 Handler 时是不是需要调用 Looper.prepare()的主要内容,如果未能解决你的问题,请参考以下文章
请教大家,在service中调用activity中handler对象?
Day475.GoogleProtobuf&Netty编解码器和handler 的调用机制 -netty