Add more control over a service's start state.
One of the problems I have been noticing is background services
sitting around running and using resources. Some times this is
due to the app developer doing this when they shouldn't, but there
are also a number of issues with the current Service interaction
model that make it very difficult (or impossible) to avoid
getting services stuck in the started state. This is a
change/enhancement to the Service API to try to address this.
The main change is that Service.onStart() has been deprecated,
replaced with a new Service.onStartCommand() that allows the
service to better control how the system should manage it. The
key part here is a new result code returned by the function, telling
the system what it should do with the service afterwards:
- START_STICKY is basically the same as the previous behavior,
where we usually leave the service running. The only difference
is that it if it gets restarted because its process is killed,
onStartCommand() will be called on the new service with a null
Intent instead of not being called at all.
- START_NOT_STICKY says that, upon returning to the system, if
its process is killed with no remaining start commands to
deliver, then the service will be stopped instead of restarted.
This makes a lot more sense for services that are intended to
only run while executing commands sent to them.
- START_REDELIVER_INTENT is like START_NOT_STICKY, except if
the service's process is killed before it calls stopSelf()
for a given intent, that intent will be re-delivered to it
until it completes (unless after 4 or more tries it still
can't complete, at which point we give up).
Change-Id: I978f5ca420d70023d1b5e7f97de639d09381f8ad
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index e045105..1e915b4 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1215,6 +1215,7 @@
private static final class ServiceArgsData {
IBinder token;
int startId;
+ int flags;
Intent args;
public String toString() {
return "ServiceArgsData{token=" + token + " startId=" + startId
@@ -1417,10 +1418,11 @@
}
public final void scheduleServiceArgs(IBinder token, int startId,
- Intent args) {
+ int flags ,Intent args) {
ServiceArgsData s = new ServiceArgsData();
s.token = token;
s.startId = startId;
+ s.flags = flags;
s.args = args;
queueOrSendMessage(H.SERVICE_ARGS, s);
@@ -2684,7 +2686,8 @@
service.onCreate();
mServices.put(data.token, service);
try {
- ActivityManagerNative.getDefault().serviceDoneExecuting(data.token);
+ ActivityManagerNative.getDefault().serviceDoneExecuting(
+ data.token, 0, 0, 0);
} catch (RemoteException e) {
// nothing to do.
}
@@ -2710,7 +2713,7 @@
} else {
s.onRebind(data.intent);
ActivityManagerNative.getDefault().serviceDoneExecuting(
- data.token);
+ data.token, 0, 0, 0);
}
} catch (RemoteException ex) {
}
@@ -2736,7 +2739,7 @@
data.token, data.intent, doRebind);
} else {
ActivityManagerNative.getDefault().serviceDoneExecuting(
- data.token);
+ data.token, 0, 0, 0);
}
} catch (RemoteException ex) {
}
@@ -2773,9 +2776,10 @@
if (data.args != null) {
data.args.setExtrasClassLoader(s.getClassLoader());
}
- s.onStart(data.args, data.startId);
+ int res = s.onStartCommand(data.args, data.flags, data.startId);
try {
- ActivityManagerNative.getDefault().serviceDoneExecuting(data.token);
+ ActivityManagerNative.getDefault().serviceDoneExecuting(
+ data.token, 1, data.startId, res);
} catch (RemoteException e) {
// nothing to do.
}
@@ -2801,7 +2805,8 @@
((ApplicationContext) context).scheduleFinalCleanup(who, "Service");
}
try {
- ActivityManagerNative.getDefault().serviceDoneExecuting(token);
+ ActivityManagerNative.getDefault().serviceDoneExecuting(
+ token, 0, 0, 0);
} catch (RemoteException e) {
// nothing to do.
}