Reputation: 16015
I currently have a service that processes some stuff, and it is started with startService
.
I was wondering, can I call `stopService immediately after I start the service and expect it to stop the service after the processing is done?
Or does Android kill the service when I call that command?
Upvotes: 2
Views: 2013
Reputation: 63955
Android can't kill just a single Service
. All it can do is to kill the whole process and everything running within. Most apps will have just 1 process so this usually means Android kills everything or nothing. Most of the times nothing.
The lifecycle of a Service
or Activity
tells Android whether it may kill the process safely or not. The Processes and Threads describes the order in which processes are kill if there is demand for memory.
It is important to know that a Thread
started from a Service
/ Activity
it is not affected at all by onDestroy
etc. It just keeps running. Android simply does not know about that thread and won't stop it for you.
That means if you want to do some background processing you have link the lifecycle of such threads to the lifecycle of your Activity
/ Service
or Android may just kill the process and thus your thread.
Quick example of a Service that prints to logcat every second while running. Not based on IntentService
since that's more or less intended for tasks with an end.
public class MyService extends Service {
public static void start(Context context) {
context.startService(new Intent(context, MyService.class));
}
public static void stop(Context context) {
context.stopService(new Intent(context, MyService.class));
}
private final ExecutorService mBackgroundThread = Executors.newSingleThreadExecutor();
private Future<?> mRunningTask;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// startService -> start thread.
if (mRunningTask == null) {
// prevents task from being submitted multiple times.
// actually not necessary when using a single thread executor.
mRunningTask = mBackgroundThread.submit(mRunnable);
}
return START_STICKY;
}
private Runnable mRunnable = new Runnable() {
@Override
public void run() {
while (!Thread.interrupted()) {
try {
// Do something
Log.d("Service", "I'm alive");
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.d("Service", "Got interrupted", e);
Thread.currentThread().interrupt();
}
}
}
};
@Override
public void onDestroy() {
// stopService > kill thread.
mBackgroundThread.shutdownNow();
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
Upvotes: 0
Reputation: 1006744
One hopes that "processes some stuff" is done in a background thread, assuming that it will take more than a couple of milliseconds.
Android is largely oblivious to such a background thread. stopService()
will trigger onDestroy()
of the service, and the service will go away. The thread, however, will continue to run, until it terminates on its own, or until the process is terminated.
can I call `stopService immediately after I start the service and expect it to stop the service after the processing is done?
Only if "the processing" is done on the main application thread (e.g., in the body of onStartCommand()
), which, again, is not a good idea if such work will take more than a couple of milliseconds. And, if that indeed is the case, there's no good reason for having a service in the first place.
If you want to have a service that:
stopService()
)then use an IntentService
.
Upvotes: 2
Reputation: 1149
According to the documentation:
stopService(Intent service)
Request that a given application service be stopped. If the service is not running, nothing happens. Otherwise it is stopped. Note that calls to startService() are not counted -- this stops the service no matter how many times it was started.
Note that if a stopped service still has ServiceConnection objects bound to it with the BIND_AUTO_CREATE set, it will not be destroyed until all of these bindings are removed. See the Service documentation for more details on a service's lifecycle.
Upvotes: -1