Hi!

I have a problem when I try to close my service when my internet connection is lost.

It sound simple but my service is a bit more complicated than the normal ones, it runs an executor service with a priorityQueue implemented in it.

I handle the tasks which I want to execute withing the service itself, and bind it to each task create to notify the service to keep going until his job is done (managed in local DB)

when I lose internet connection, i detect it through a broadcast receiver.
I had 2 approaches:

1.  Now I wanted to remove the entire queue from my executor (I got this method on my service), can only be done inside the service because he stores an arrayList of Future object that contains the tasks. When I regain connection, I reset my tasks statuses to "need to run" use my notifyService method to tell the service to check for new tasks to run, which he will take all the canceled ones.

2. just shut the service down and reactivate it when i regain connection

In both approaches I encountered a problem because I cant bind a service inside a broadcast receiver, which means I cant access the future object and cant cancels the tasks, same issue happened with just shutting it down because the stopService will wait for my threads to finish before destroying the service(they never do cause of no connectivity), any attempts to use executor.shutdownNow() has to be done withing the service itself

Is there any other ideas to solve this issue?

My service:


@Override
public void onCreate() {
startInForeground();// starts the background service
super.onCreate();
isActive = true;
mDbHelper = new DBHelper(this);
Utility.w("SERVICE CREATED");
mExecutor = (PriorityExecutor) PriorityExecutor.newFixedThreadPool(3);
mDbHelper.resetQueue();
if (mDbHelper.requestsExists()) {
notifyService(true);
} else {
stopForeground(true);
mExecutor.shutdown();
this.stopSelf();
}
mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
}

notifyService is the core method of this service and will handle most cases, it basically tells the service to execute a new task from my task lists. 


public void notifyService(boolean firstRun) {
isActive = true;
int requestsToExecute = 0;
mDbHelper = new DBHelper(this);

int allRequestsDone = mDbHelper.allRequestsDone(); // 1 - all requests done, 0 - there are requests to execute, -1 - error
if (!firstRun) {// if its not the first run, we check if there are still requests to execute to know weather or not to shut down the service
requestsToExecute = 1;
if (allRequestsDone == 1) {
Intent myActivityIntent = new Intent(this, CloudActivity.class);
PendingIntent startActivityPendingIntent = PendingIntent.getActivity(this, 0, myActivityIntent, 0);

stopForeground(true);
mExecutor.shutdown();
this.stopSelf();
return;
}
} else {// if it is the first run
if (allRequestsDone == -1) {
Utility.w("Error in allrequestDone!");
}
}
Map requestMap = mDbHelper.getRequestsToExcute(requestsToExecute);
Set keySet = requestMap.keySet();
for (Integer iteratorNext : keySet) {
file = new File(requestMap.get(iteratorNext));
int state = mDbHelper.getRequestState(iteratorNext);
switch (state) {
case 10:
// send a checkTask Not implemented yet
break;
case 20:
MetaDataTask newMetaDataTask = new MetaDataTask(this, iteratorNext, file);
mDbHelper.advanceRequestState(iteratorNext, state + 1);
Future metadataFuture = mExecutor.execute(newMetaDataTask, 6);
mFutureTasks.put(iteratorNext, metadataFuture);
mTasks.put(iteratorNext, newMetaDataTask);
break;
case 30:
// send thumbnailTask not implemented yet
break;
case 40:
MediaUploadTask newMediaUploadTask = new MediaUploadTask(this, iteratorNext, file);
mDbHelper.advanceRequestState(iteratorNext, state + 1);
Future mediaUploadFuture = mExecutor.execute(newMediaUploadTask, 10);
mFutureTasks.put(iteratorNext, mediaUploadFuture);
mTasks.put(iteratorNext, newMediaUploadTask);
break;
}
}
}

Each task runs on a different thread (ThreadPoolExecutor), binds to my service, then call the notifyService method so the next one will start executing

I investigated this entire subject alone, I am aware there might be major flaws in my approach, and would love to hear any mistakes I made.

I know thats a bit complicated and ill try to explain the best a i can
Thanks alot in advance!