web-dev-qa-db-fra.com

java.lang.RuntimeException: gestionnaire (Android.os.Handler) envoyant un message à un gestionnaire sur un thread mort

dans mon application, j'utilise IntentService pour l'envoi de SMS.

    @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());                       
                }
            }
        }
    }
}

lors de l'exécution de l'application, j'obtiens l'erreur suivante:

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)

Mon SMSReceiver est situé dans une autre classe . Comment puis-je résoudre ce problème? ... Merci.

53
eyal

Le problème ici est que vous créez une Toast dans un thread géré par la IntentService. Le système utilisera la Handler associée à ce fil pour afficher et masquer la Toast.

Tout d'abord, la variable Toast sera affichée correctement, mais lorsque le système essaiera de la masquer, une fois la méthode onHandleIntent terminée, l'erreur "Envoi du message à un gestionnaire sur un thread mort" sera renvoyée car le thread sur lequel la Toast a été créée est n'est plus valide, et la Toast ne disparaîtra pas.

Pour éviter cela, vous devez montrer à la Toast l'envoi d'un message dans le fil principal. Voici un exemple:

    // 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();
        }
    });
151
rubenlop88

Affichez Toast sur IntentService.

@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();                
        }
    });
}

source: - https://stackoverflow.com/a/5420929/4565853

3
Finava Vipul

Je pense que vous devez vérifier une condition:

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

L'application va juste vous avertir de cette erreur. Bien sûr, c’est pour la plupart non fatale . Mais s’il existe de nombreuses utilisations de ce gestionnaire, ces avertissements ralentiront l’application. 

0
CodeToLife