sending message to a handler on a dead thread

I am working on a background service that for a period of time poll to a server something. The point is that: I have an IntentService (called NotificationsService) which calls another service, but the response of this request does’nt get back. And in the logcat appears:

06-19 05:12:00.151: W/MessageQueue(6436): Handler (android.os.Handler) {416659f0} sending message to a Handler on a dead thread
06-19 05:12:00.151: W/MessageQueue(6436): java.lang.RuntimeException: Handler (android.os.Handler) {416659f0} sending message to a Handler on a dead thread
06-19 05:12:00.151: W/MessageQueue(6436):   at android.os.MessageQueue.enqueueMessage(MessageQueue.java:196)
06-19 05:12:00.151: W/MessageQueue(6436):   at android.os.Handler.sendMessageAtTime(Handler.java:473)
06-19 05:12:00.151: W/MessageQueue(6436):   at android.os.Handler.sendMessageDelayed(Handler.java:446)
06-19 05:12:00.151: W/MessageQueue(6436):   at android.os.Handler.post(Handler.java:263)
06-19 05:12:00.151: W/MessageQueue(6436):   at android.os.ResultReceiver$MyResultReceiver.send(ResultReceiver.java:50)

I looked here problems similar but I got confused (I’m not using any AsyncTask, and I’ve looked for CommonsWare code wakefullIntent but i didn’t understand it).

  • Android setX() and setY() behaving weird
  • NFC: What is the difference between S-beam and Android beam?
  • Android button textAppearance
  • Android - Fade out bitmap image on canvas
  • Enable Exception C++
  • How to Customize AppCompat Material Button Style?
  • Here it’s the code for NotificationsService.java

    public class NotificationsService extends IntentService {
    private static  int TIME_INTERVAL_MILIS=90000;
    private static final int REFRESH=10;
    private  NotificationManager noteManager;
    private static List<FlightStatusNote> flights= new ArrayList<FlightStatusNote>();
    
    
    
    public NotificationsService(){
        super("NotificationsService");
    
    }
    
    @Override
    public void onCreate(){
        Log.d("notificationsSservice","onCreate");
        super.onCreate();
        noteManager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
    }
    
    
    
    @Override
    protected void onHandleIntent(Intent intent) {
        Log.d("NotificationsService","Me llamaron");
    
        Log.d("NotificationsService", "intervalo:"+NotificationsService.TIME_INTERVAL_MILIS);
            Log.d("NotificationsService","Itero por cada vuelo registrado para notificar");
            for(FlightStatusNote f: flights){
                FlightStatus fly=f.getFlight();
                Log.d("NotificationsService","Vuelo id:"+fly.getAirlineId()+fly.getNumberFlight());
                Intent intentaux=new Intent(Intent.ACTION_SYNC,null,getBaseContext(),FlightStatusService.class);
                intentaux.putExtra("airlineFlight", fly.getAirlineId());
                intentaux.putExtra("numberFlight",fly.getNumberFlight() );
                intentaux.putExtra("receiver", new ResultReceiver(new Handler()) {
    
                    @Override
                    protected void onReceiveResult(int resultCode, Bundle resultData) {
                        super.onReceiveResult(resultCode, resultData);
                        Log.d("notificationsService","response received");
                        if (resultCode == FlightStatusService.STATUS_OK) {
                            List<FlightStatus> fly =  (List<FlightStatus>)resultData.getSerializable("return");
                            for(FlightStatus f: fly){
                                int indexNote=flights.indexOf(new FlightStatusNote(f,null));
                                FlightStatusNote fsNote=flights.get(indexNote);
                                List<String> changes=fsNote.hasChanged(f);
                                if(changes==null){
                                    Log.d("notificationsService","changes is null");
                                }
                                else{
                                    Log.d("notficationsService", "comething changed");
                                    createNotification(f, changes);
                                }
    
                            }
    
    
                        }
    
                    }
    
                });
                startService(intentaux);
        }
    
            AlarmManager alarmMgr = (AlarmManager) getBaseContext().getSystemService(Context.ALARM_SERVICE);
              PendingIntent pendingIntent =  PendingIntent.getBroadcast(getBaseContext(), 0, new Intent(getBaseContext(), DealAlarmReceiver.class), 0);
              alarmMgr.set(AlarmManager.RTC, System.currentTimeMillis()+NotificationsService.TIME_INTERVAL_MILIS, pendingIntent);
    
    }
    }
    

    If anyone can help me, I would appreciate it a lot!
    Cheers!

    Edit: I think the problem is that the Log “response received” it doesn’t appear.

    Related posts:

    can any one provide me example of Two_line_list_item in Android?
    Android ActionBar setCheckable() not working
    android background image slows down app
    How can I get root permissions through the Android SDK?
    How to add a page to the beginning of ViewPager?
    how can I pass data to android Market using the new scheme on chrome?
  • Screen Capture in android
  • How to mock getApplicationContext
  • Implementing a File Picker in Android and copying the selected file to another location
  • Glide load thumbnail not working
  • how to use toUppercase(locale) in android 4.2?
  • Android, How can I rotate an arrow (image) around a fixed point?
  • 5 Solutions collect form web for “sending message to a handler on a dead thread”

    IntentServices create a new thread when you call the onHandleIntent method, and then kills that thread as soon as that onHandleIntent method returns.

    You need to create your listener somewhere else, IntentServices aren’t safe for setting up listeners because they die. They’re mainly used for executing a short task outside of the main thread. See a similar question here.

    Edit: Also see documentation on IntentService.

    I cannot reply back because I’m new, but basically what ‘jpalm’ mentioned is the most accurate answer.

    Basically there is a thing that I understood playing with ServiceIntent: they will die inmediately they finish. Meaning that if you submit a work in the framework (like starting an Activity); the Framework could immediately go back to you to tell you ‘startService(intentaux)’ returned OK or whatever (I’m not an expert, I’m new on this too:P ), because it found that your thread is dead already!!!.

    When you start your Activity,If you intentionally force your thread be somehow alive until you get the response, this errors doesn’t happen.

    See http://developer.android.com/guide/components/services.html. Modify the example to not wait, then Toast start crashing sending clear messages like this, even when you believe you are not using ASYNC Method.

    07-24 08:03:16.309: W/MessageQueue(1937): java.lang.RuntimeException: Handler (android.os.Handler) {b1016d80} sending message to a Handler on a dead thread
    07-24 08:03:16.309: W/MessageQueue(1937):   at android.os.MessageQueue.enqueueMessage(MessageQueue.java:320)
    07-24 08:03:16.309: W/MessageQueue(1937):   at android.os.Handler.enqueueMessage(Handler.java:626)
    07-24 08:03:16.309: W/MessageQueue(1937):   at android.os.Handler.sendMessageAtTime(Handler.java:595)
    07-24 08:03:16.309: W/MessageQueue(1937):   at android.os.Handler.sendMessageDelayed(Handler.java:566)
    07-24 08:03:16.309: W/MessageQueue(1937):   at android.os.Handler.post(Handler.java:326)
    07-24 08:03:16.309: W/MessageQueue(1937):   at android.widget.Toast$TN.hide(Toast.java:370)
    07-24 08:03:16.309: W/MessageQueue(1937):   at android.app.ITransientNotification$Stub.onTransact(ITransientNotification.java:55)
    07-24 08:03:16.309: W/MessageQueue(1937):   at android.os.Binder.execTransact(Binder.java:404)
    07-24 08:03:16.309: W/MessageQueue(1937):   at dalvik.system.NativeStart.run(Native Method)
    

    I have to say the documentation of android.developers is pretty good but very concise (ULTRA ZIP), meaning that you will have to read and read, word by word, and then when you look into a dictionary after being desperated… you say: IT WAS ALWAYS HERE! :O

    it is like a Bible, but for developers ๐Ÿ™‚ and somehow we are becoming Android prophets ๐Ÿ˜›

    Each Handler has a Looper, and a Looper has a HandlerThread. The general problem is when a Handler becomes associated with thread that stop running. If someone tries to use the Handler, it will fail with the message “sending message to a Handler on a dead thread”.

    If you just do new Handler() it becomes associated with the current thread. If you do this on a thread that’s going to go away (such as the worker thread for an IntentService) you’ll have the issue. The problem of course isn’t limited to this root cause, it can happen in any number of ways.

    Any easy fix is to construct your Handler like,

    Handler h = new Handler(Looper.getMainLooper());
    

    This associates the Handler with the main looper, or the main application thread which will never die. Another more complex fix is to create a dedicated thread for the Handler,

    HandlerThread ht = new HandlerThread(getClass().getName());
    ht.start();
    Handler handler = new Handler(ht.getLooper());
    

    Note that you need to explicitly quit() the HandlerThread when you are done with the associated Handler.

    look here

                 intentaux.putExtra("receiver", new ResultReceiver(new Handler()) {
    
                @Override
                protected void onReceiveResult(int resultCode, Bundle resultData) {
                    super.onReceiveResult(resultCode, resultData);
                    Log.d("notificationsService","response received");
                    if (resultCode == FlightStatusService.STATUS_OK) {
                        List<FlightStatus> fly =  (List<FlightStatus>)resultData.getSerializable("return");
                        for(FlightStatus f: fly){
                            int indexNote=flights.indexOf(new FlightStatusNote(f,null));
                            FlightStatusNote fsNote=flights.get(indexNote);
                            List<String> changes=fsNote.hasChanged(f);
                            if(changes==null){
                                Log.d("notificationsService","changes is null");
                            }
                            else{
                                Log.d("notficationsService", "comething changed");
                                createNotification(f, changes);
                            }
    
                        }
    
    
                    }
    
                }
    

    you post an annonimously defined handler object – why not tie that handler object to an activity (process) and see if the code breaks then? Essentially, passing in a handler variable instead of a new handler object.

    that way, all ResultReceivers will use the same Handler object instead of a private one.

    the main reason is you have put a message on a queue which has not looper to loop.
    however,you can use “getMainLooper()” to pass as a param to the โ€œHandlerโ€ you create.

    public AutoHandler(Context context, Looper looper) {
        super(looper);
        this.context = context;
    }
    

    and you can create an Instance of AutoHandler like this:

    autoHandler = new AutoHandler(this, getMainLooper());
    
    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.