web-dev-qa-db-ja.com

java.lang.RuntimeException:デッドスレッドでハンドラーにメッセージを送信するハンドラー(Android.os.Handler)

私のアプリでは、SMSの送信に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は別のクラスにあります。この問題を解決するにはどうすればよいですか?ありがとう。エアル。

57
eyal

ここでの問題は、Toastによって管理されるスレッド内にIntentServiceを作成していることです。システムは、このスレッドに関連付けられたHandlerを使用して、Toastの表示と非表示を切り替えます。

最初にToastが正しく表示されますが、システムがそれを非表示にしようとすると、onHandleIntentメソッドが終了した後、「デッドスレッドのハンドラーにメッセージを送信しています」というエラーがスローされます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();
        }
    });
156
rubenlop88

ToastIntentServiceに表示します。このコードを試してください。

@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/456585

5
Finava Vipul

条件を確認する必要があると思います。

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

アプリケーションはこのエラーについて警告するだけです。もちろん、それはほとんど致命的なものではありません。ただし、このハンドラーの使用が多数発生する場合、これらの警告はアプリケーションの速度を低下させます。

0
CodeToLife