Sending message to a handler on a dead thread

The slightly more subtle message is: handler( android.os.Handler ) {215ddea8} sending message to a Handler on a dead thread。

In another case, when using mediaplayer in intentservice to play the ring tone, the error is also reproduced. The message is: handler) {42414500} sending message to a handler on a dead thread.

The complete information is as follows:

W/ActivityManager( 1394): getTasks: caller 10034 is using old GET_ TASKS but privileged; allowing

W/MessageQueue( 7666): Handler ( android.os.Handler ) {215ddea8} sending message to a Handler on a dead thread

W/MessageQueue( 7666): java.lang.IllegalStateException : Handler ( android.os.Handler ) {215ddea8} sending message to a Handler on a dead thread

W/MessageQueue( 7666):  at android.os.MessageQueue .enqueueMessage( MessageQueue.java:325 )

W/MessageQueue( 7666):  at android.os.Handler .enqueueMessage( Handler.java:635 )

W/MessageQueue( 7666):  at android.os.Handler .sendMessageAtTime( Handler.java:604 )

W/MessageQueue( 7666):  at android.os.Handler .sendMessageDelayed( Handler.java:574 )

W/MessageQueue( 7666):  at android.os.Handler .postDelayed( Handler.java:398 )

W/MessageQueue( 7666):  at com.bandwidthx.library .l.a(S ourceFile:367 )

W/MessageQueue( 7666):  at com.bandwidthx.library .l.B(S ourceFile:357 )

W/MessageQueue( 7666):  at com.bandwidthx.library . BxApproval.aZ (S ourceFile:4563 )

W/MessageQueue( 7666):  at com.bandwidthx.library . BxApproval.aT (S ourceFile:4440 )

W/MessageQueue( 7666):  at com.bandwidthx.library . BxApproval.aS (S ourceFile:4431 )

W/MessageQueue( 7666):  at com.bandwidthx.library . BxApproval.aG (S ourceFile:4044 )

W/MessageQueue( 7666):  at com.bandwidthx.library .l.a(S ourceFile:1320 )

W/MessageQueue( 7666):  at com.bandwidthx.library .l.j(S ourceFile:1275 )

W/MessageQueue( 7666):  at com.bandwidthx.library .q.w(S ourceFile:2280 )

W/MessageQueue( 7666):  at com.bandwidthx.library .q.a(S ourceFile:3399 )

W/MessageQueue( 7666):  at com.bandwidthx.library .q.a(S ourceFile:3103 )

W/MessageQueue( 7666):  at com.bandwidthx.library .q$1.a(S ourceFile:1959 )

W/MessageQueue( 7666):  at com.bandwidthx.library .q$1.doInBackground(S ourceFile:1928 )

W/MessageQueue( 7666):  at android.os.AsyncTask $2.call( AsyncTask.java:292 )
W/MessageQueue( 7666):  at java.util.concurrent . FutureTask.run ( FutureTask.java:237 )

W/MessageQueue( 7666):  at android.os.AsyncTask $SerialExecutor$1.run( AsyncTask.java:231 )

W/MessageQueue( 7666):  at java.util.concurrent . ThreadPoolExecutor.runWorker ( ThreadPoolExecutor.java:1112 )

W/MessageQueue( 7666):  at java.util.concurrent .ThreadPoolExecutor$ Worker.run ( ThreadPoolExecutor.java:587 )

W/MessageQueue( 7666):  at java.lang.Thread .run( Thread.java:818 )

It’s estimated that looper, message queue and so on have been rotten by you.

 

I’ll just give you a brief summary (of course, there are also very detailed ones below)

Once a thread’s message loop exits, it can no longer send messages to it, otherwise runtimeException will be thrown.
That’s what you see in general:

"RuntimeException: Handler{xxxx} sending message to a Handler on a dead thread"。

Generally speaking, if you implement your own looper and handler, it is recommended that Looper.prepare After (), call Looper.myLooper () to get a reference to the thread looper.
Purpose: 0. You can call quit() to terminate the service thread. 1. When receiving a message, check whether the message loop has exited

 

It is worth mentioning that the thread is terminated. Sometimes it is not terminated by yourself. It may be caused by some normal timing of the system (you just don’t pay attention to this sequence, and then you don’t pay attention to it when writing code)


 

The above has been made clear, and the following is the detailed information & amp; wordy demarcation line

 

Case: (using intentservice to send SMS, the code is as follows)

Inside the intentservice, it is actually a worker thread opened.

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

(people with a clear eye will know that there is something wrong with the catch sentence)

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

It turned out to be a mistake

Google took a look at the information, and the website said:

The reason is that you create a toast in a thread whose life cycle is controlled by intentservice. The phone will display the toast first, and then hide it with the handler of the thread; Close the toast, but when onhandleintent ends, the thread will hang up, and then the handler bound to the thread will not exist, and the toast will not close after the completion. What should I do? Send it to the main thread. The handeler of its toast is still alive. You can hide toast.)

 

What about the solution? (simple, rough)

 


 

What questions do you have to say?

Why send a message to a dead thread?

Because the onhandle intent (intent intent) ends, the thread is gone. What’s going on?

 

Handler is gone, so can’t hide toast?

If I remember correctly, the life cycle of this toast should be controlled by notification manager service, right?

 

(analysis of intentservice source code) — todo

Analysis of toast life cycle source code

Read More: