活套调用不止一次引起"发送消息到处理程序上一个死线程" [英] Calling Looper more than once causes "sending message to a Handler on a dead thread"

查看:141
本文介绍了活套调用不止一次引起"发送消息到处理程序上一个死线程"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用一个Executor [固定的线程池]我自己的ThreadFactory,增加了一个活套:

I am using an Executor [fixed thread pool] with my own ThreadFactory that adds a Looper:

Handler HANDLER = new Handler();
Executor    THREADS = Executors.newFixedThreadPool(THREAD_POOL_SIZE, new ThreadFactory() {
    @Override public Thread newThread(Runnable runnable) {
        return new MyThread(new Runnable() {
            @Override public void run() {
                Looper.prepare();
                runnable.run();
            }
        });
    }
});

private static class MyHandler extends Handler {
    public boolean fail;
        public void handleMessage(Message msg) {
        switch(msg.what) {
            case 1:
                this.fail = msg.arg1 == 1;
                Looper.myLooper().quit();
                break;
            }
        }
    }
}

我正在运行一个线程,使得网络请求,但如果网络出现故障,我想可以向用户显示一个对话框消息。这个过程是相当涉及,因为它需要制作和显示在UI线程的请求。我可以等待用户的反应,对话框通过简单地添加一个循环,网线,并等待要发送从UI线程的消息。这让我封装在一段时间(TRYAGAIN)线程的网络请求。所有工作良好时除外Looper.loop()方法被调用所述第二时间(显示一个第二网络错误对话框之后)和一个消息由对话发送(在UI线程)到网络线程的处理程序:

THREADS.execute(new Runnable() {
    private MyHandler   myHandler   = new MyHandler();
    @Override public void run() {
        boolean tryAgain    = true;
        while(tryAgain) {
            try {
                switch(request) {
                    [Handle network requests]
                }
                tryAgain    = false;

            } catch(IOException e) {
                // The network is unavailable.  Ask the user if we should try again.
                e.printStackTrace();

            } finally {
                if(tryAgain) {
                    HANDLER.post(new Runnable() {   // The UI thread
                        @Override public void run() {
                            theAlertDialog.show();
                        }
                    });

                    // Wait for the results from the dialog which lives in the UI thread.
                    Looper.loop();

                    // At this point the dialog has informed us of our answer.
                    tryAgain = !myHandler.fail;
                }
            }
        }
    }
});

在AlertDialog实例是一个OnClickListener:

In the AlertDialog instance is an OnClickListener:

DialogInterface.OnClickListener myOnclickListener = new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int id) {
        Message msg = myHandler.obtainMessage(1);
        msg.setTarget(this.handler);
        msg.sendToTarget();
    }
}

我已经检查该线程仍然活跃 handler.getLooper()。getThread()的isAlive()它总是返回true,但它仍然给了我发送消息到处理程序上的死线。它是如何的留言/处理程序决定该线程是死了吗?难道不应该依赖.isAlive()方法?最后我想避免复制线程管理打造成为了Android OS: - )

I've checked that the thread is still active with handler.getLooper().getThread().isAlive() which always returns true but it still gives me "sending message to a Handler on a dead thread". How is it that the Message/Handler has decided that the thread is dead? Shouldn't it rely on the .isAlive() method? In the end I am trying to avoid replicating the thread management build into the Android OS :-)

推荐答案

如果您检查的android / OS / MessageQueue.java源,你可以看到类似以下

If you check the source in android/os/MessageQueue.java, you can see something like the following

  if (mQuiting) {
                RuntimeException e = new RuntimeException(
                    msg.target + " sending message to a Handler on a dead thread");
                Log.w("MessageQueue", e.getMessage(), e);
                return false;
            } else if (msg.target == null) {
                mQuiting = true;
            }
   }

因此​​,消息队列后Looper.quit()被称为第一次,因为它加入队列一条消息,一个空的目标,这是不可思议的标识符消息队列停止入队,并出现死的基本不可用

So the message queue is basically unusable after Looper.quit() has been called the first time, as it enqueues a Message with a null target, which is the magical identifier for the message queue to stop enqueuing and appear "dead".

这篇关于活套调用不止一次引起"发送消息到处理程序上一个死线程"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆