6

我正在尝试实现从不同线程监听同一个 Looper 的处理程序。

下面我有两个处理程序,一个在主线程中创建,另一个在子线程中创建,但是两者都被初始化为在 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 }

我究竟做错了什么?感谢您的阅读。

4

2 回答 2

12

每个Handler实例都控制Message目标,无法让它们共享,因此发送到 a 的每条消息或帖子Handler仅由该实例执行。

Looper指示将在哪个线程上执行发送的消息/可运行文件。在您的代码中,两个处理程序都将handleMessage()在主线程上执行,尽管是在单独的线程上创建的。Looper这就是您可以将实例传递给Handler... 如果您传递 no的真正原因Looper那么Handler在创建它的线程上执行代码(该线程也必须是一个Looper线程)。

此外,因此没有理由创建多个处理程序以这种方式发布数据。singleHandler被设计为从多个线程发送消息,它们都在 a 中序列化MessageQueue并在所选Looper线程上执行。您可以直接mMain从后台线程发布以在该线程上执行代码。Looper在这种情况下,在该代码已经在主线程上传递是多余的。

于 2013-03-21T02:31:00.690 回答
1

发送到 a 的消息Handler将仅由 that 处理Handler,即使它正在共享 a Looper

埋在 Handler 的源代码中的是这一行

msg.target = this;

这确保没有其他Handler人会碰它。

于 2013-03-21T02:16:16.950 回答