问题
Use case:
When geofence triggers we need to contact server ASAP. We have solved this with an implicit BroadcastReceiver calling a Service for several years, but problematic in new versions due to Doze and Oreo background restrictions.
Attempted fixes:
We moved geofence registering from implicit -> explicit broadcast receiver to get around the "background mode" restriction.
We tried to do it as in Googles examples, i.e. the broadcast receiver calling enqueueWork() on a JobIntentService. The problem with this is that we often noticed a long "lag" between when the job was scheduled and when it actually ran. Our record is over one hour!
So, we instead tried to move all functionality into the BroadcastReceiver and use goAsync() to do the network call. (if you try to do the network operation synchronously you get a "no network from main thread" exception).
It works insofar that we can start a thread and it executes the code, but the network operation gives us trouble.
Problem:
So, our current solution, because of the above issues, is an explicit BroadcastReceiver, using goAsync() to do the server call.
However, the network call works very intermittently. We quite often get "java.net.SocketException: Socket is closed" errors. It is not a server issue, and it always works when called from our "regular" application code.
I am not sure why this happens, but I suspect Doze mode? Although, I am not sure how I can get that when the Receiver is actually called by the geofence trigger.
Questions:
Does anyone know why the network operation would fail from our goAsync()? Again, the threading works, its just that we get socket errors on the actual network operation.
Is there, in newer versions of Android, any way from a geofence trigger to make a network call directly, as we're trying to do, besides the things we've already tried?
Pointers and thoughts much appreciated!
来源:https://stackoverflow.com/questions/52257295/why-is-network-access-in-my-geofence-broadcast-receiver-unreliable