活套调用不止一次引起"发送消息到处理程序上一个死线程" [英] Calling Looper more than once causes "sending message to a Handler on a dead thread"
问题描述
我使用一个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屋!