【问题标题】:java.lang.RuntimeException: Handler (android.os.Handler) sending message to a Handler on a dead threadjava.lang.RuntimeException:处理程序(android.os.Handler)向死线程上的处理程序发送消息
【发布时间】:2013-12-02 06:37:47
【问题描述】:

在我的应用中,我使用 IntentService 发送短信。

    @Override
protected void onHandleIntent(Intent intent) {
    Bundle data = intent.getExtras();
    String[] recipients = null;
    String message = getString(R.string.unknown_event);
    String name = getString(R.string.app_name);
    if (data != null && data.containsKey(Constants.Services.RECIPIENTS)) {
        recipients = data.getStringArray(Constants.Services.RECIPIENTS);
        name = data.getString(Constants.Services.NAME);
        message = data.getString(Constants.Services.MESSAGE);
        for (int i = 0; i < recipients.length; i++) {
            if(!StringUtils.isNullOrEmpty(recipients[i])) {
                try {
                    Intent sendIntent = new Intent(this, SMSReceiver.class);
                    sendIntent.setAction(Constants.SMS.SEND_ACTION);
                    PendingIntent sendPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, sendIntent, PendingIntent.FLAG_UPDATE_CURRENT);
                    Intent deliveryIntent = new Intent(this, SMSReceiver.class);
                    deliveryIntent.setAction(Constants.SMS.DELIVERED_ACTION);
                    PendingIntent deliveryPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, deliveryIntent, PendingIntent.FLAG_UPDATE_CURRENT);
                    SmsManager.getDefault().sendTextMessage(recipients[i].trim(), null, "[" + name + "] " + message, sendPendingIntent, deliveryPendingIntent);
                } catch (Exception e) {
                    Log.e(TAG, "sendTextMessage", e);
                    e.printStackTrace();
                    Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
                    MainActivity.instance.writeToLogFile(e.getMessage(), System.currentTimeMillis());                       
                }
            }
        }
    }
}

在运行应用程序时,我收到以下错误:

W/MessageQueue(7180): Handler (android.os.Handler) {42586468} sending message to a Handler on a dead thread
W/MessageQueue(7180): java.lang.RuntimeException: Handler (android.os.Handler) {42586468} sending message to a Handler on a dead thread
W/MessageQueue(7180):   at android.os.MessageQueue.enqueueMessage(MessageQueue.java:294)
W/MessageQueue(7180):   at android.os.Handler.enqueueMessage(Handler.java:618)
W/MessageQueue(7180):   at android.os.Handler.sendMessageAtTime(Handler.java:587)
W/MessageQueue(7180):   at android.os.Handler.sendMessageDelayed(Handler.java:558)
W/MessageQueue(7180):   at android.os.Handler.post(Handler.java:323)
W/MessageQueue(7180):   at android.widget.Toast$TN.hide(Toast.java:367)
W/MessageQueue(7180):   at android.app.ITransientNotification$Stub.onTransact(ITransientNotification.java:55)
W/MessageQueue(7180):   at android.os.Binder.execTransact(Binder.java:351)
W/MessageQueue(7180):   at dalvik.system.NativeStart.run(Native Method)

我的 SMSReceiver 位于另一个类中。 我该如何解决这个问题? 谢谢; 艾尔。

【问题讨论】:

  • 您是否将此服务添加到清单中?
  • 是的。 IntentService 毕竟是真正的服务......

标签: android android-intent service handler runtimeexception


【解决方案1】:

我认为你需要检查一个条件:

mHandler.getLooper().getThread().isAlive()

应用程序只会警告您此错误。当然,它大多不是致命的。 但是如果这个处理程序有很多衍生的使用,这些警告会减慢应用程序的速度。

【讨论】:

    【解决方案2】:

    IntentService 上显示 Toast。 试试这个代码..

    @Override
    public void onCreate() {
        super.onCreate();
        mHandler = new Handler();
    }
    
    @Override
    protected void onHandleIntent(Intent intent) {
        mHandler.post(new Runnable() {            
            @Override
            public void run() {
                Toast.makeText(MyIntentService.this, "Test", Toast.LENGTH_LONG).show();                
            }
        });
    }
    

    来源:-https://stackoverflow.com/a/5420929/4565853

    【讨论】:

      【解决方案3】:

      这里的问题是您在由IntentService 管理的线程内创建Toast。系统将使用与该线程关联的Handler来显示和隐藏Toast

      首先Toast会正确显示,但是当系统试图隐藏它时,在onHandleIntent方法完成后,会抛出错误“sending message to a Handler on a dead thread”,因为线程创建Toast 的位置不再有效,Toast 不会消失。

      为避免这种情况,您应该显示Toast 向主线程发布消息。这是一个例子:

          // create a handler to post messages to the main thread
          Handler mHandler = new Handler(getMainLooper());
          mHandler.post(new Runnable() {
              @Override
              public void run() {
                  Toast.makeText(getApplicationContext(), "test", Toast.LENGTH_SHORT).show();
              }
          });
      

      【讨论】:

      • @rubenlop88 我仍然不明白当我使用可运行文件时问题是如何解决的。我的理解是,问题是,当 onHandle 被调用时,它会调用 Toast,然后它会退出,然后 Toast 会被隐藏?那是顺序吗,但是如果是这种情况,那么当我使用runnable时,runnable线程也应该在隐藏Toast之前杀死自己。我在这里想念什么?谢谢
      • @Kraken Runnable 用于在应用程序的主线程上创建Toast。如果您不使用Runnable,则Toast 将在IntentService 管理的线程中创建。如果IntentService 的线程结束得太快,那么Toast 将不会被关闭。
      • 太棒了。工作正常,但就我而言,问题是根本没有显示 Toast。
      猜你喜欢
      • 1970-01-01
      • 2013-06-18
      • 2019-08-30
      • 1970-01-01
      • 2016-10-05
      • 2016-04-24
      • 1970-01-01
      • 1970-01-01
      • 2011-04-08
      相关资源
      最近更新 更多