我正在尝试实现从不同线程监听同一个Looper的Handler。
下面我有两个处理程序,一个在主线程中创建,另一个在子线程中创建,但是两个都初始化为侦听Main Looper。
private Handler mMain;
public static final ThreadPoolExecutor tpe =
(ThreadPoolExecutor) Executors.newCachedThreadPool();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMain = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
Log.wtf("", "main:" + msg);
}
};
tpe.execute(new Runnable() {
private Handler tChild = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
Log.wtf("", "child:" + msg);
}
};
@Override
public void run() {
Log.wtf("", "send msg to main looper");
tChild.sendEmptyMessage(100);
}
});
}
但是当我发送如下消息时,只有子处理程序打印消息。主处理程序不会收到消息。
03-20 22:02:26.754: A/(12857): send msg to main looper
03-20 22:02:26.847: A/(12857): child:{ what=100 when=-8ms }
我做错了什么?谢谢你的阅读。
答案 0 :(得分:10)
每个Handler
实例控制Message
目标,并且无法让它们共享,因此发送到Handler
的每条消息或帖子只会由该实例执行。< / p>
Looper
表示将执行发送的消息/可运行的哪个线程。在您的代码中,两个处理程序都将在主线程上执行handleMessage()
,尽管它是在不同的线程上创建的。这就是你可以将Looper
个实例传递给Handler
的真正原因......如果你没有传递Looper
,那么 Handler
会在创建它的线程上执行代码(必须也是Looper
线程)。
此外,由于这个原因,没有理由创建多个处理程序以这种方式发布数据。单个Handler
旨在从多个线程发送消息,它们都在MessageQueue
中序列化并在选定的Looper
线程上执行。您可以从后台线程直接发送到mMain
以执行该线程上的代码。在这种情况下,传递Looper
是多余的,因为该代码已经在主线程上。
答案 1 :(得分:1)
发送给Handler
的邮件只会由Handler
处理,即使它正在共享Looper
。
埋在Handler的源代码中就是
行msg.target = this;
这可以确保没有其他Handler
会触及它。