I'd like to set up a network task in an Android app using AlarmManager.setInexactRepeating(...).
I have registered my BroadcastReceiver in AndroidManifest.xml with the following entry:
<receiver
android:name="com.vandenmars.colortrek.analytics.CTAUploadService"
android:process=":sync"/>
Now, if I simply run my network request with a blocking HttpURLConnection from onReceive(), I get a NetworkOnMainThreadException!?!?
Weird... I thought the whole point of the AlarmManager was to call onReceive on a background-thread...
Which leads me to question 1:
Is it possible to force AlarmManager to call onReceive on a background thread rather than a Main thread? Do I need to declare something differently in AndroidManifest.xml?
I've tried to just work around this issue by setting up an AsyncTask for my network request inside onReceive and the exception goes away. The problem I'm having now is that some Android devices take forever to time out a network request that should fail because of an intermittent network issue or server problem. So, now (if I set the repeat-interval to something tiny) I have a bunch of AsyncTasks piling up in a queue that are trying to complete the same request and hang, waiting for the first request to fail. And when the network issue is resolved, all pending AsyncTasks break loose one after the other in a gigantic deluge of network requests.
To solve this, I tried simply keeping a flag in an instance variable around in my code that prevents another AsyncTask from being scheduled before the previous one completes. Unfortunately, this didn't work as expected, as every invocation from the AlarmManager created a fresh instance of my BroadcastReceiver, resetting the flag...
It does work if I make this flag static
to attach it to the class itself rather than an instance of it, but this leads me to question 2:
Can I rely on this approach or is it ever possible that a BroadcastReceiver is called in such a way that there are two processes (?) or so of it active that have different "instances" of static variables?
And finally question 3:
If I can't rely on this approach, is there a good alternative?
I'd rather not have to hit the disk with this flag since I don't want to use up flash-write-cycles if I don't have to...
PS: I realize that there are other ways to do networking in the background, like GCM, JobScheduler, SyncAdapters, ... that may fix this issue for me or be otherwise considered "the right way to do it". Unfortunately they all have some form of issue (sketchy permissions, weird system changes, API level requirements, ...) that make them useless to me. So, I do need to use AlarmManager for this.