1

I have implemented Push Notification in my appliction. Once the push message is received I call a webservice with the help of AsyncTask. This works fine when the application is being used or is in the memory. But if I stop the application from settings and then if the message is pushed to the device, there is an exception such as "sending message to a Handler on a dead thread". This is probably since the app is not live.

Can someone let me know if its alright to actually remove AsyncTask from push notification receiver and just handle the message?

Regards Sunil

sunil
  • 9,541
  • 18
  • 66
  • 88

2 Answers2

10

This is due to a bug in AsyncTask in the Android framework. AsyncTask.java has the following code:

private static final InternalHandler sHandler = new InternalHandler();

It expects this to be initialized on the main thread, but that is not guaranteed since it will be initialized on whichever thread happens to cause the class to run its static initializers. I reproduced this issue where the Handler references a worker thread.

A common pattern that causes this to happen is using the class IntentService. The C2DM sample code does this.

A simple workaround is to add the following code to the application's onCreate method:

Class.forName("android.os.AsyncTask");

This will force AsyncTask to be initialized in the main thread. I filed a bug on this in the android bug database. See http://code.google.com/p/android/issues/detail?id=20915.

Jonathan Perlow
  • 951
  • 1
  • 8
  • 12
  • Thank you. In my case the GCM works fine for a Nexus7 at 4.1 but not for a Kobo at 2.3. I would have NEVER found this without your gracious and knowledgeable guidance – user462990 Jan 10 '13 at 15:57
1

IMO AsyncTask should be only used as a helper for background tasks related to Activities (that is, UI).

In your case I would use an IntentService, it is a Service that is prepared to execute background task. So:

  1. A new notification is pushed to the device.
  2. You receive the notification in your broadcast receiver.
  3. You fire a IntentService to perform synchronization against the WS
  4. The IntentService does its job, when finishes it raises a broadcast event.

In your Activity attach a broadcast receiver for the broadcast in step 4. This way your UI gets notified if it's present, else nothing bad happens. Optionally you can register a default broadcast receiver in your Manifest to handle the broadcast of step 4 and, for example, display a status bar notification.

aromero
  • 25,681
  • 6
  • 57
  • 79
  • I have done only with the BroadcastReceiver. I mean C2DMReceiver which will be receiving the push messages. I hope its fine doing everything in C2DMReceiver only and not calling any IntentService. – sunil Sep 06 '11 at 13:29
  • Sorry I can't understand your words :/ – aromero Sep 06 '11 at 15:05
  • I meant I am not using any IntentService and using broadcast doing the task in BroadcastReceiver only since I think the broadcast receiver will not block the UI. – sunil Sep 17 '11 at 05:32