问题是,我告诉我的主题使用 mHandler 来执行 Looper ?
谢谢。 我使用以下代码:
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
答案 0 :(得分:4)
要更好地理解,请创建一个正常的Thread
并尝试在该线程的Handler
方法中创建run()
。你会得到RuntimeException
的说法:
无法在未调用的线程内创建处理程序
Looper.prepare()
现在在创建run()
之前在Handler
方法中调用Looper.prepare()会创建与调用线程相关联的新Looper
对象 。您混淆的原因是Looper.prepare()不会将Thread
作为参数。它不需要,因为它是一个静态方法,它在内部获取当前正在运行的线程的ThreadLocal
。最多只有一个Looper
与任何Thread
相关联。
现在,通过内部呼叫new Handler()
,调用Handler
会将新的Looper
对象与当前Thread
的{{1}}相关联。您可以在同一个线程中使用自己的Callback创建多个Looper.myLooper()
。所有处理程序都会从同一Handler
的消息队列中获取消息。
答案 1 :(得分:4)
问题是,我告诉我的线程使用mHandler 打环器?
您不需要明确告诉它,因为系统(框架)会为您完成。实例化Handler
时,它将自动获得对当前Thread
的消息队列的访问权限。引用你的评论:
系统如何知道将邮件发送到
mHandler
Handler
?
我将在下面详述。
这是Android中android.os.Handler
的构造函数:
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
如您所见,首先它会获得您当前Looper
的{{1}}。 Thread
的源代码如下:
Looper.myLooper()
它从线程本地存储中获取它。之后,当您使用此public static final Looper myLooper() {
return (Looper)sThreadLocal.get();
}
发送Message
时,Handler
实际上将自己设为Handler
的收件人:这就是Message
将知道在Looper
到达时派遣的位置。详情:
当您致电Message
时,最终会运行此代码(在许多其他代码行中):
mHandler.sendMessage()
如您所见,它将 MessageQueue queue = mQueue;
boolean sent = false;
if (queue != null) {
msg.target = this; // msg is your Message instance
sent = queue.enqueueMessage(msg, uptimeMillis);
}
实例设置为Handler
的目标。因此,稍后,当调度Message
时,它将包含Message
作为其目标。这就是Handler
将知道它应该将哪个Looper
发送给它的方式。详细信息,当您调用Handler
时,队列中的每个Looper.loop()
个实例都会发生以下情况:
Message
msg.target.dispatchMessage(msg);
代码如下:
dispatchMessage()
请注意上次 public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
来电 - 这正是您的handleMessage(msg)
覆盖!
答案 2 :(得分:2)
你什么都没说。来自Handler
文档:
每个Handler实例都与一个线程相关联 线程的消息队列。当您创建新的Handler时,它将被绑定 正在创建它的线程的线程/消息队列 - 来自 那一点,它将为该消息传递消息和可运行的消息 队列并在它们从消息队列中出来时执行它们。
处理程序自动绑定到线程的消息队列。您只实现回调,而系统将负责所有事情,即调度和处理消息。实际上我同意,使用两个静态方法,如Looper.prepare()
和Looper.loop()
并自动推断事物,使模式感觉像黑魔法:)