Prevent multiple copies of an Android service

17,211

Solution 1

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!

Solution 2

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.

Solution 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.

Share:
17,211

Related videos on Youtube

StarTraX
Author by

StarTraX

Updated on June 04, 2022

Comments

  • StarTraX
    StarTraX almost 2 years

    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.

    • Noundla Sandeep
      Noundla Sandeep over 8 years
      Don't go read all the answers. As mentioned StartTrax below, this happened when he extends the "IntentService" instead of "Service" class. "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!"
  • StarTraX
    StarTraX about 12 years
    OK it's getting a bit clearer, thanks, but the second part of my question remains unanswered - why the service doesn't appear in getRunningServices.
  • yydl
    yydl about 12 years
    @StarTraX Can you share some code? Perhaps you are stopping the service?
  • David Wasser
    David Wasser over 10 years
    That's great. Can you accept your own answer please? That will help others who come to this question for advice.
  • Hugo Delsing
    Hugo Delsing almost 5 years
    Even though the service can only run once and OnCreate is called once, Android expects you to create a seperate thread for long running code. So in rare occasions when you call Task.Run in OnCreate, that task can run twice shortly when the service is stopped and started again quickly. The thread from the first OnCreate hasn't finished yet while the second call to OnCreate after restart will spawn another thread.