javaandroidsingletonandroid-serviceandroid-lifecycle

Using Service as singleton in Android


Is it a bad practice to create a Service that works as a singleton? I mean a Service that is never stopped and that contains some private data that some other engines and Activities would use, so the Service could have something like:

public class CustomService extends Service {
    private List<Profile> mProfiles;
    private static CustomService instance;

     public static CustomService getInstance() {
         if(instance == null) {
             instance = new CustomService();
         }
         return instance;
     }

     public List<Profile> getProfiles() {
          return mProfiles;
     }

     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
         ...
     }
     ...
}

The reason of doing a Service instead of just a singleton is that it must work independently of the application, as when it starts it connects a websocket that should never be closed and do not depend on the application. What would you suggest me to do? Is there a better way to re-use the Service in order to have some data (for instance the mProfiles array) available from other engines and Activities?

I've read somewhere that a Service works as a singleton, but I don't know how to access the private variables from any other point in application.


Solution

  • Is it a bad practice to create a service that works as a singleton?

    It is redundant and, in the way you suggest, not going to work from the point of view of Android Service as application component which is to perform its functionality with respect to

    Such an intention of an application component is reached by

    That said, brings to the fact that application components are tied to the Application instance hosted by OS process and can't run independently.


    Regarding your approach, there are two scenarios:

    1. CustomService's default constructor is private as per the pattern.

    By calling getInstance() a single instance of CustomService is created. The instance is just a Java object (singleton) that has nothing in common with Android Service application component. The onStart(), onStartCommand() etc. methods will never be called by the system.

    An attempt to start the "service" (declared in the manifest) with startService(Intent) will fail with IllegalAccessException: access to constructor not allowed.

    2. CustomService's default constructor is public (as per the code posted).

    If the service is declared in AndroidManifest and the default constructor is empty, startService() won't fail, however getInstance() will create another instance of CustomService that won't be treated as Android Service application component.

    This isn't a singleton.


    What would you suggest me to do? Is there a better way to re-use the service in order to have some data (for instance the mProfiles array) available from other engines and activities?

    Use Service as per the documentation and pick the kind of communication you need:

    Finally, Service in Android is a singleton. There is only one instance of each service in the system. It starts on demand and handles all pending Intents / bound clients. Once it's done or explicitly stopped, it will be destroyed.