Here is what I do now:
I have a service that runs in the background and reads user location. Each time a valid location is read (there are some parameters like distance and time) an IntentService is started to send that location to a web server
The app, that uses the tracking service, also has some web calls, depending on what options the user presses. Right now, the app simply calls the web service in a asynctask.
Some code: The location service fires the IntentService, each time a good location is received, like this:
Intent intentService = new Intent(LocationLoggerService.this, LocationManagerIntentService.class);
intentService.putExtra(Constants.MESSAGE_LOCATION, readLocation);
startService(intentService);
The intentservice processes the intent:
@Override
protected void onHandleIntent(Intent intent) {
LocationInfo location = intent.getExtras().getParcelable(Constants.MESSAGE_LOCATION);
.... //Do the web call and broadcast result to app
}
Here are the changes I need to make:
The IntentService and the app must not call web server in the same time. As the implementation is made now, this is not possible, as they act independent. I was thinking of passing all the web calls from the app, to the IntentService by creating intents for all of them. Would this work? In case that there was a location web sending, a new intent from an app call would be put in queue and executed right after current call?
If there are multiple location sending in queue because of low network speed, the app call, needs to be put in front of queue and not wait for all existing intents to finish, just for the current one. Is there a way to put an intent on top of queue?
Thank you.
Later edit:
Here are the changes I've made.
- Created a custom intent service
public abstract class PriorityIntentService extends Service { private final AtomicInteger intentsCount = new AtomicInteger(); protected void intentFinished() { intentsCount.decrementAndGet(); } private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } public final boolean sendPriorityMessage(Message msg) { intentsCount.incrementAndGet(); int priority = msg.arg2; if (priority == 0) { return sendMessageAtFrontOfQueue(msg); } else { return sendMessage(msg); } } @Override public void handleMessage(Message msg) { onHandleIntent((Intent) msg.obj); if (intentsCount.get() == 0) { // stopSelf(msg.arg1); stopSelf(); } } } @Override public void onStart(Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; if (intent.getExtras().getInt(Constants.MESSAGE_PRIORITY) == 0) { msg.arg2 = 0; } else { msg.arg2 = 1; } mServiceHandler.sendPriorityMessage(msg); // mServiceHandler.sendMessage(msg); } }
- And the other service:
public class LocationManagerIntentService extends PriorityIntentService { @Override protected void onHandleIntent(Intent intent) { intentFinished(); } }