2010-09-04 49 views
1

我使用一个Executor [固定的线程池]我自己的ThreadFactory,增加了一个活套“上死线程发送消息到一个处理程序”:调用尺蠖不止一次引起

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线程中进行AND显示请求。我可以等待用户对对话框的响应,方法是简单地向网络线程添加一个Loop,并等待从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:

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 :-)

回答

6

如果您在Android设备/ OS/MessageQueue.java源,你可以看到类似下面的

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()被称为第一时间之后,因为它排入一则短消息具有空靶,这是消息队列停止排队和出现“死”神奇标识符。

+1

嘿,对不起,晚了一年答复。我不确定我收到了关于此事的通知: - / – Nate 2012-09-11 14:42:29

相关问题