使用Looper.getMainLooper()初始化的处理程序不响应消息回调

时间:2013-03-21 02:09:28

标签: android multithreading handler looper

我正在尝试实现从不同线程监听同一个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 }

我做错了什么?谢谢你的阅读。

2 个答案:

答案 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会触及它。