Android AlarmManager details?
I'm working on my first Android application and I'm having problems using AlarmManager. My application schedules an alarm to check a few URLs for data. Well, sometimes when the alarm runs, I get an "ANR" error in logcat (which I assume stands for application not responding, by the dialog that I get on my phone). The error shows every process running on the phone with some statistics, after the following log entries:
07-30 14:11:07.442: WARN/ActivityManager(2735): Timeout of broadcast BroadcastRecord{48d749d8 null} - receiver=android.os.BinderProxy@49088bc0
07-30 14:11:07.442: WARN/ActivityManager(2735): Receiver during timeout: ResolveInfo{48d74950 com.shaddow.courseChecker.CourseAlarm p=0 o=0 m=0x0}
07-30 14:11:07.477: INFO/Process(2735): Sending signal. PID: 25006 SIG: 3
07-30 14:11:07.477: INFO/dalvikvm(25006): threadid=3: reacting to signal 3
07-30 14:11:07.567: INFO/dalvikvm(25006): Wrote stack traces to '/data/anr/traces.txt'
Followed by a bunch more SIG 3's to what looks like every process, then:
07-30 14:11:08.118: ERROR/ActivityManager(2735): ANR in com.shaddow.courseChecker
07-30 14:11:08.118: ERROR/ActivityManager(2735): Reason: Broadcast of Intent { flg=0x4 cmp=com.shaddow.courseChecker/.CourseAlarm (has extras) }
07-30 14:11:08.118: ERROR/ActivityManager(2735): Load: 0.65 / 2.76 / 2.49
07-30 14:11:08.118: ERROR/ActivityManager(2735): CPU usage from 420741ms to 26ms ago:
I would assume that this is caused by code getting stuck on downloading the html page for a bit too long? After all of this happens, my onReceive() finishes executing fine.
As f开发者_StackOverflow社区or fixing it... Do I have to run my code in a separate thread in onReceive() for it to not send an ANR to the user? If I do that, will it allow the phone to sleep before it is done executing? Or, should I start a service with a partial wake lock?
Do I have to run my code in a separate thread in onReceive() for it to not send an ANR to the user?
Yes. More accurately:
- Write an
IntentService
, where you do the download work inonHandleIntent()
- Have your
AlarmManager
alarm start that service via agetService()
PendingIntent
If you intend on having this work done even if the device is asleep, using a _WAKEUP
alarm, you will want to consider using my WakefulIntentService
and following the required pattern for keeping the device awake while doing this work -- the demo/
project on that site illustrates this.
精彩评论