views:

1500

answers:

2

I'm not having much luck with updating an app widget with AlarmManager generated broadcasts. Here's what I do:

Initializing AlarmManager on AppWidgetProvider#onEnabled

AlarmManager alarms = (AlarmManager) context.getSystemService(
        Context.ALARM_SERVICE);
    alarms.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 
    SystemClock.elapsedRealtime(), 60000, pendingIntent);

I also define broadcast receiver that simply listens for the updates that fired by the AlarmManager. When update is fired code runs AsyncTask that makes a network call. When the AsyncTask is completed (onPostExecute) it uses previously obtained instance of AppWidgetManager to update the widget(s). It all actually runs well until in the logs I see message "Process com.foo.myapp (pid 12345) has died" after which the AlarmManager never fires another update.

Do I need to have some sort of check which will restart the alarms? For example when user access the parent app of the widget? How do I ensure that I can complete the long running task and come back to the widget if my app dies in the middle of the request?

+3  A: 

When update is fired code runs AsyncTask that makes a network call.

If this is inside the BroadcastReceiver, that won't work. You cannot safely fork threads from a BroadcastReceiver, and AsyncTask effectively forks a thread to do its task asynchronously.

Instead, you should delegate long-running work to a service started from the alarm BroadcastReceiver.

CommonsWare
OK, I buy that - what I don't understand: why my alarm never re-fires after the app is killed? Or is it because the BroadcastReceiver dies with the app? But then, even if I run the service what happens if the app is killed the same way? I think I'm missing some fundamental knowledge here
DroidIn.net
Also - after starting the service and acquiring a lock should I then spawn a thread for my long-running task or just run it as part of the service?
DroidIn.net
I do not know why AlarmManager never fires again, but I recommend fixing the known problem (forking a thread in BroadcastReceiver) and hope that clears up the unknown problem (lobotomized alarm). IntentService automatically runs onHandleIntent() in a background thread, so you do not need to fork your own if you are using IntentService.
CommonsWare
Thanks Mark - trying it this morning but oh, boy why this has to be so complicated?!
DroidIn.net
BTW - as a side note. Mark has great overview (my last nigh bedtime reading) of this in Advanced Android chapter 13
DroidIn.net
A: 

AlarmManager issue with App-Widget on low RAM

Hi,

We are facing an issue with our app-widget on Low RAM. When the available RAM size is less than 70MB, Widget process starts dying and showing the message, "Process has died. Low Memory: No more background processes." and restarting the process again. It is repeating for a long time and whenever there is enough memory widget starts working normally. But again when we do some other action which uses memory, widget again dies. I tried to figure out the reason for that and it seems the AlarmManager which runs for making the updates causes the issue.

Has anybody encountered this kind of issue? It would be great if you can help me on this to solve.

Thanks in advance, Linto

Linto
This is pretty much expected. Android will shutdown processes on low memory. You need program for it that's why you have methods like onPause and onResume
DroidIn.net
Also - you shouldn't post question in the answers section. I would post this as independent question - I'm sure you will get much better chance to get an answer
DroidIn.net
Sorry for that. I don't have methods like onPause and onResume in WidgetProvider class. I have only limited events like onReceive, onUpdate, etc.
Linto