Prevent multiple copies of an Android service

2020-02-26 05:25发布

问题:

The doco for startService states "If this service is not already running, it will be instantiated and started (creating a process for it if needed); if it is running then it remains running." I'm finding that each call to startService appears to be starting a separate instance of the service, in that the work that the service is doing (in my test case, trivially writing to a new log file) is being done again for each call. I'm trying to detect the service by looping through ActivityManager... getRunningServices(Integer.MAX_VALUE)) but it's not showing up. Android 2.3.3 on SGS 11 I'm missing something here. I understood that the Service's onCreate() method only gets called when it's created, and that since I have a continuous process running in the Service (the

In my Activity's onResume method I'm starting the service ("myService")with:

    Intent intent = new Intent(this, myService.class);
startService(intent);

In MyService I have an onCreate like

@Override 

public void onCreate(){
    super.onCreate();
    ...

from where I set a timer, using a TimerTask, which writes to a log file once/second.

This works as expected - I can see the log being written. In the Activity's onResume method, before calling the StartService method, I'm checking to see if the myService service exists by calling a checkForRunningService method containing

for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
    if (service.service.getClassName().contentEquals("com.gpsanimator.startrax.myService")) {
    Toast.makeText(getApplicationContext(), "Service IS SO running: ", Toast.LENGTH_SHORT).show();
        return true;
}

This never finds the myService service, even though it appears to be running as it's happily writing to the log file.

Eeach time I resume my Activity, the onCreate method of my myService service gets called - it generates a new log file and starts writing to it as well as the original log file being continuously updated. Doesn't the Service get started the first time the startService is called? And then continue running? Shouldn't subsequent calls to startService() find the Service already running and therefore not trigger the onCreate() method again? But that's not what I'm seeing. It seems that every call to startService() is triggering the Service's onCreate() method.

It's obviously more complicated than this, and I would like to get to the bottom of it.

回答1:

It all depends on which method you're putting the code in.

When you call startService only one service will be created at a given time. If the service already exists it will be reused. So the code in onCreate() will only be called if a service did not already exist.

However, each time you call startService the code in onStartCommand() will be run no matter what.

So yes only one instance of a service ever exists at a given time, but calling startService can have an effect.



回答2:

The problem was I had declared my myService class to extend IntentService, not Service! Once I fixed that, it all worked as per the book!



回答3:

IntentService stops immediately (automatically) after work is performed, BUT if you start it again till work finishes you are reused existing service instance and onCreate isn't called. So please be careful with IntentServices.



回答4:

You are extending IntentService which will work as a worker thread. The service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work. So in your case your service stop itself after completing the task so it creates multiple times. You should use Service class and bind with the component.