This is the 8th day of my participation in Gwen Challenge

This article is based onAndroid 9.0.0The source code

framework/base/core/java/andorid/app/Service.java

Introduction to the

To quote the official definition:

A Service is an application component that can run operations in the background for a long time without providing a user interface. Services can be started by other application components and continue to run in the background even if the user switches to another application. In addition, components can be bound to services to interact with or even perform interprocess communication (IPC). For example, a service can handle network transactions, play music, perform file I/O, or interact with a content provider, all in the background.

** Note: The ** service runs in the main thread of its managed process and neither creates its own thread nor runs in a separate process (unless otherwise specified). This means that if the service is going to perform any CPU intensive work or blocking operations, such as MP3 playback or networking, a new thread should be created within the service to do the work. By using a separate thread, you can reduce the risk of an “application non-response” (ANR) error, while the main thread of the application can continue to focus on running the interaction between the user and the Activity.

A Service is an application component that can operate in the background for a long time without using a user interface. So the question is, since it doesn’t use a user interface, how does it know when to start doing what? The answer is — it can form some kind of relationship with other reference components so that it can perform the appropriate action at the appropriate time based on the information it sends in.

In general, there are two kinds of connections: startService() and bindService(). Both of these relationships can get a Service up and running, but they differ in many other ways.

How to start the service The way to stop service How a service communicates with the component that starts it The service life cycle
startService The service is started when the startService() method is called in the other component The service stops running when the stopSelf() method is called within a service, or when the stopService() method is called by another component The default communication mode is not provided, and the service runs independently after it is started Once started, a service can run in the background indefinitely, even if the component that started it has been destroyed, until it is stopped
bindService The service is started when the bindService() method is called in the other component The service will stop running after all components bound to the service are destroyed or they all call the unbindService() method With ServiceConnection, components can interact with services, send requests, get results, and even perform these operations across processes using IPC The service stops when all its bound components are unbound (either because the component has been destroyed or because it called the unbindService() method)

Note: 1. “Other Components” in the table do not include Broadcast Receiver, which cannot bindService but can startService

2. StartService () does not conflict with bindService(). The same service may have both a component calling startService() to start it and a component binding to it. When the same service has both of these relationships with other components, its life cycle changes and the service must be stopped from both perspectives to truly stop.

Create a Service

There are two steps to create a Service

  • Create a class that inherits fromService(or a subclass of it, e.gIntentService), override some key callback methods inside, such asonStartCommand().onBind()Etc.
  • Declare it in the SSE document and configure other attributes as required.

To be fair, this is very much like creating a new Activity.

  • The onCreate () in eachServiceThe method will be called once and only during the life cycle of theonStartCommand()As well asonBind()Previously, we could have done some one-time initialization in this method.
  • OnStartCommand () when other components passstartService()Methods to start theService“, the method will be called.
  • OnBind () when other components passbindService()The methods andServiceAfter binding, this method will be called. This method has oneIBinder, which means that one must be returned when overwriting itIBinderObject, which is used to support other components withServiceBetween — plus, if you don’t want thisServiceIs bound to another component by returning a null value in this method.
  • This is onDestroy ()ServiceThe last method called in a lifetime, when this method is called,ServiceIt will be destroyed. So we should clean up some resources in this method, such as registered listeners and so on.

Only the Android :name attribute is mandatory for use in the sse document. However, sometimes proper configuration can make development go more smoothly, so it’s important to know what properties can be declared by registering a Service.

<service
    android:enabled=["true"|"false"]
    android:exported=["true"|"false"]
    android:icon="drawable resource"
    android:isolatedProcess=["true"|"false"]
    android:label="string resource"
    android:name="string"
    android:permission="string"
    android:process="string" >
</service>
Copy the code

For details, please refer to the official website

  • Android :enabled: This if trueServiceCan be instantiated by the system, if false, not. The default is true
  • Android: Exported: If true, components of other applications can also call thisServiceAnd can interact with it, if false, only withServiceThe same application or applications with the same user ID can enable or bind this functionService. Its default value depends onServiceIs there aintent filters. If no filter is present, only the specified filter is availableServiceThe exact class name of, that is, thisServiceIt can only be used internally – other applications don’t know its class name. The default value exported in this case is false. Conversely, as long as there is a filter, it means thatServiceExported is the default value true for external use
  • -Serena: It’s an android iconServiceThe icon of
  • Android :isolatedProcess: If set to true, thisServiceWill run in a special process that is separate from the rest of the system and we can only communicate with it through the Service API. The default is false.
  • Android :label: this is displayed to the userServiceThe name. If not set, the label attribute is used by default.
  • The android: name: this oneServicePath name, such as “com. Lingdage. Demo. ServiceDemo”. This property is the only one that must be filled in.
  • Other components must have the specified permissions to start thisService.
  • android:process : ServiceName of the running process. Started by defaultServiceIs running on theThe main processIn the.

Demo

public class ServiceDemo extends Service {

    private static final String TAG = "ServiceDome";
    
    @Override
    public void onCreate(a) {
        super.onCreate();
        Log.d(TAG, "onCreate");
        // The service is called only once when it is created, and some one-time initialization can be done here
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand");
        // This method is called when another component calls the startService() method
        // This is where the main operations of the service are performed
        return super.onStartCommand(intent, flags, startId);
    }
    
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind");
        This method is called when other components call the bindService() method
        // If you do not want the service to be bound, return null here
        return null;
    }
    
    @Override
    public void onDestroy(a) {
        Log.d(TAG, "onDestroy");
        // The last method of the service call
        // Recycle the resource here
        super.onDestroy(); }}Copy the code

Note: Each Service must be declared in the manifest

<service android:name="com.example.servicetest.ServiceDemo" >.</service>
Copy the code

Now that we have defined our own ServiceDemo class by inheriting Service and declaring our ServiceDemo in the Manifest, we should start our own Service.

Note that the onStartCommand() method must return an integer. An integer is a value that describes how the system should continue to run the service if it terminates (as mentioned above, the default implementation of IntentService will handle this for you, though you can modify it). The value returned from onStartCommand() must be one of the following constants:

  • START_NOT_STICKY

    If the system terminates the service after onStartCommand() returns, the system will not rebuild the service unless there is a pending Intent to deliver. This is the safest option to avoid running the service when it is not necessary and when the application can easily restart all outstanding jobs.

  • START_STICKY

    If the system terminates the service after onStartCommand() returns, the service is rebuilt and onStartCommand() is called, but the last Intent is not redelivered. Instead, onStartCommand() is called with an empty Intent unless there is a pending Intent to start the service (in which case those intents will be delivered). This applies to media players (or similar services) that do not execute commands but run indefinitely and wait for jobs.

  • START_REDELIVER_INTENT

    If the system terminates the service after onStartCommand() returns, the service is rebuilt and onStartCommand() is called with the last Intent passed to the service. Any pending intents are delivered in sequence. This applies to services that actively perform jobs that should be restored immediately, such as downloading files.

Start the Service

Another component can start a particular Service by calling the startService() method, which causes the onStartCommand() method in the Service to be called. When the startService() method is called, other components need to pass an Intent parameter in the method. The Service will then receive the Intent in onStartCommand() and fetch some data. For example, if an Activity wants to store some data in a database, I can pass the data to a Service with an Intent, and then ask the Service to connect to the database and store the data. At this point, the user can do anything else — even destroy the Activity — without affecting the Service’s ability to store data.

When a Service is started in this way, its life cycle is independent of the component that started it. It can run indefinitely in the background, as long as the Service does not call stopSelf() and no other component calls stopService() for it.

Alternatively, if you decide to start a Service this way and do not want the Service to be bound, then perhaps you have a better choice than the traditional creation of a class that inherits the Service — IntentService.

IntentService is much simpler than Service. Note, however, that if you have a requirement for the Service to handle multiple requests at the same time, then you have to inherit the Service. At this point you have to deal with the work line yourself

demo

We start ServiceDemo with an Intent object and call the startService() method

Intent startIntent = new Intent(this, ServiceDemo.class);  
startService(startIntent);
Copy the code

Note that if we execute the code above by clicking on the Button, the onCreate() and onStartCommand() methods will be executed on the first click, but only onStartCommand() will be executed on the second click.

Why is that?

This is because the onCreate() method is only called when the Service is created for the first time. If the current Service has already been created (ServiceDemo was created the first time), the onCreate() method will not be executed no matter how the startService() method is called.

Once started, what should we do when we want to stop the service?

We also stop ServiceDemo with an Intent object and call the stopService() method

Intent stopIntent = new Intent(this, ServiceDemo.class);
stopService(stopIntent);
Copy the code

Stop the Service

Starting a service must manage its own life cycle. That is, the system does not stop or destroy the service unless it must reclaim memory resources, and the service continues to run after onStartCommand() returns. Therefore, the service must stop running by itself by calling stopSelf(), or another component must stop it by calling stopService().

Once the request is made to stop the service using stopSelf() or stopService(), the system destroys the service as soon as possible.

However, if the service is processing multiple onStartCommand() requests at the same time, you should not stop the service after processing one start request, because you may already have received a new start request (stopping the service at the end of the first request terminates the second request). To avoid this problem, you can use stopSelf(int) to ensure that the service stop request is always based on the most recent start request. That is, when stopSelf(int) is called, the ID of the start request (the startId passed to onStartCommand()) that corresponds to the ID of the stop request is passed. Then, if the service receives a new start request before you can call stopSelf(int), the ID does not match and the service will not stop.

** Note: ** To avoid wasting system resources and consuming battery power, the application must stop its service after the work is completed. If necessary, other components can stop the service by calling stopService(). Even if binding is enabled for the service, you must always stop the service yourself once the service receives a call to onStartCommand().

Creating a binding service

A binding service allows an application component to bind to it by calling bindService() in order to create a long-term connection (components are generally not allowed to start it by calling startService()).

Create a binding service if you need to interact with services in activities and other application components, or if you need to expose some application functionality to other applications through interprocess communication (IPC).

To create a binding service, the onBind() callback method must be implemented to return the IBinder that defines the interface to communicate with the service. Other application components can then call bindService() to retrieve the interface and start calling methods on the service. A service is only used by the application component it is bound to, so if no component is bound to the service, the system will destroy the service (you do not have to stop binding the service as if it was started with onStartCommand()).

To create a bound service, you must first define an interface that specifies how the client communicates with the service. This interface between the service and the client must be an implementation of IBinder, and the service must return it from the onBind() callback method. Once the client receives the IBinder, it can begin to interact with the service through this interface.

Multiple clients can be bound to a service simultaneously. After the client has finished interacting with the service, it calls unbindService() to unbind. Once no client is bound to the service, the system destroys it.

BindService is a more complex way to start a service than startService, and a service that starts in this way can also do more things, such as sending requests to it from other components, receiving responses from it, and even conducting IPC through it, etc. We usually refer to the component to which it is bound as a client and call it a server.

To create a service that supports bindings, we would have to override its onBind() method. This method returns an IBinder object, which is the interface the client uses to interact with the server. And to get an IBinder interface, there are usually three ways

  • Inherit the Binder class
  • Using the Messenger class (a simplified version of AIDL)
  • Use AIDL

This is a complicated one, so we’ll do a new one. Android Bound Service

Run the service in the foreground

The foreground service is considered a service that the user is actively aware of, so the system does not consider terminating it when it runs out of memory. The foreground service must provide notifications for the status bar under the heading “In progress,” which means notifications cannot be cleared unless the service is stopped or removed from the foreground.

For example, a music player that plays music through a service should be set up to run in the foreground because the user is clearly aware of the operation. Notifications in the status bar may indicate the song being played and allow the user to start the Activity to interact with the music player.

To request that the service run foreground, call startForeground(). This method takes two parameters: an integer that uniquely identifies the Notification and Notification for the status bar. Such as:

Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
        System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this.0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
        getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);
Copy the code

** The integer ID provided by ** to startForeground() cannot be 0.

To remove the service from the foreground, call stopForeground(). This method takes a Boolean value indicating whether the status bar notification is also removed. This method does not stop the service. However, if you stop the service while it is running in the foreground, the notification will also be removed.

Manage the service life cycle

The service life cycle is much simpler than the Activity life cycle. However, paying close attention to how services are created and destroyed is even more important, because services can run in the background without the user realizing it.

The service life cycle (from creation to destruction) can follow two different paths:

  • Start the service

    This service is created when another component calls startService() and then runs indefinitely, and must be stopped by itself by calling stopSelf(). In addition, other components can stop the service by calling stopService(). After the service stops, the system will destroy it.

  • Binding service

    This service is created when another component (the client) calls bindService(). The client then communicates with the service through the IBinder interface. The client can close the connection by calling unbindService(). Multiple clients can be bound to the same service, and when all bindings are removed, the system destroys the service. (The service does not have to stop running on its own.)

The two paths are not completely independent. That is, you can bind to a service already started with startService(). For example, you can start a background music service by calling startService() with an Intent that identifies the music to play. Later, the Activity can bind to the service by calling bindService(), perhaps when the user needs a little control over the player or to get information about the currently playing song. In this case, stopService() or stopSelf() does not actually stop the service until all clients unbind.

Implement the lifecycle callback

Like activities, services have lifecycle callback methods that you can implement to monitor changes in the state of the service and perform work as appropriate. The following framework services show each lifecycle approach:

public class ExampleService extends Service {
    int mStartMode;       // indicates how to behave if the service is killed
    IBinder mBinder;      // interface for clients that bind
    boolean mAllowRebind; // indicates whether onRebind should be used

    @Override
    public void onCreate(a) {
        // The service is being created
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // The service is starting, due to a call to startService()
        return mStartMode;
    }
    @Override
    public IBinder onBind(Intent intent) {
        // A client is binding to the service with bindService()
        return mBinder;
    }
    @Override
    public boolean onUnbind(Intent intent) {
        // All clients have unbound with unbindService()
        return mAllowRebind;
    }
    @Override
    public void onRebind(Intent intent) {
        // A client is binding to the service with bindService(),
        // after onUnbind() has already been called
    }
    @Override
    public void onDestroy(a) {
        // The service is no longer used and is being destroyed}}Copy the code

** Note: ** Unlike Activity lifecycle callback methods, you do not need to invoke superclass implementations of these callback methods.

By implementing these methods, you can monitor two nested cycles of the service lifecycle:

  • The entire life cycle of the service starts when onCreate() is called and ends when onDestroy() returns. Like an Activity, the service completes its initial setup in onCreate() and releases all remaining resources in onDestroy(). For example, a music player service can create a thread to play music in onCreate() and then stop it in onDestroy().

    The onCreate() and onDestroy() methods are called for all services, whether they are created by startService() or bindService().

  • The effective life cycle of a service begins with a call to the onStartCommand() or onBind() methods. Each method has an Intent object that is passed to startService() or bindService(), respectively.

    For starting a service, the valid life cycle ends at the same time as the entire life cycle (the service is still active even after onStartCommand() returns). For binding services, the effective life cycle ends when onUnbind() returns.

** Note: ** Although the service is started and stopped by calling stopSelf() or stopService(), there is no corresponding callback for the service (no onStop() callback). Therefore, unless the service is bound to the client, it is destroyed when the service is stopped – onDestroy() is the only callback received.

Other knowledge points

Relationship between Service and Thread

Answer: There is no relationship between services and Threads!

  • The difference between the two concepts

    • Thread is the smallest unit of program execution and the basic unit of CPU allocation. UI Thread in Android system is also a kind of Thread. Of course, Thread can also be used to perform some time-consuming asynchronous operations.

    • A Service is an Android mechanism that runs on the main thread, which is hosted by a system process. The communication between it and other components is similar to client and Server, which is a lightweight IPC communication. Binder is the carrier of this communication, which is a kind of IPC that exchanges information in Linux layer, while the so-called Service background tasks are just components without UI.

  • The tasks are very different

    • inAndroidIn the system, threads generally refer to worker threads (background threads), while the main thread is a special worker thread, which is responsible for dispatching events to corresponding user interface widgets, such as drawing events and event responses. Therefore, in order to ensure the responsiveness of the application UI, time-consuming operations cannot be performed on the main thread. If you perform operations that cannot be completed quickly, make sure that they are performed on a separate worker thread.
    • ServiceIt isAndroidA component of a system that normally runs onThe main threadIn, therefore inServiceDo not perform time-consuming operations. Otherwise, the system reports an ANR exceptionServiceFor background services, most of the reason is that it has no UI itself, the user can not perceive (of course, can also use some means to let the user know), but if you need to letServiceYou can perform time-consuming tasks in theServiceTo open a separate thread to execute.
  • Usage Scenarios of both

    • When you need to perform time-consuming network or database queries and other tasks that block UI threads or are cpu-intensive, you should use worker threads so that the UI threads don’t get tied up and affect the user experience.

    • Use services in applications that need to run in the background for long periods of time without interaction. For example, playing music is performed in the background via Service+Notification and displayed in the Notification bar.

  • The best way to use both

In most cases, Threads and services are used together. For example, a file is downloaded by a Service in the background +Notification displayed in the Notification bar + Threads are downloaded asynchronously. For example, an application maintains a Service to obtain push services from the network. IntentService (Thread and Service) : IntentService (Thread and Service) : IntentService (Thread) : IntentService IntentService is not suitable for all scenarios, but it is easy to use, the code is simple, you do not need to create a Service instance and create a thread at the same time, which is great in some scenarios! Since IntentService is a single worker thread, tasks need to be queued, so it is not suitable for most multitasking situations. And why not just create it inside the Activity? This is because it is difficult for an Activity to control threads, and when an Activity is destroyed, there is no other way to retrieve instances of previously created child threads. And child threads created in one Activity cannot be operated on by another Activity. But a Service is different. All activities can be associated with a Service (via binding) and can then easily manipulate its methods, even if the Activity is destroyed and then simply re-associated with the Service. Binder instances of the original Service are retrieved. Therefore, by using a Service to handle background tasks, the Activity can finish without worrying about not being able to control the background tasks.

The types of Service

Sorted by location of operation

category The difference between advantages disadvantages application
Local Services (Local) The service is attached to the main process The service is attached to the main process instead of an independent process, which saves resources to some extent. In addition, the Local service does not need IPC or AIDL because it is in the same process. The corresponding bindService is much more convenient. After the main process is killed, the service terminates. Very common applications such as: music playback services.
Remote Service (Remote) The service is a separate process The service is a separate process with a process name in the format of the package name plus the Android: Process string you specify. As an independent process, the service is still running when the process of the Activity is killed and is not affected by other processes, which helps provide services for multiple processes with high flexibility. The service is a separate process that takes up resources and is a bit more cumbersome to use AIDL for IPC. Some services that provide system services are resident.

Classification by operation type

category The difference between application
The front desk service A positive Notification is displayed in the Notification column, When the service is terminated, the Notification in the Notification column will also disappear, so that users can be notified to a certain extent. Common ones are music streaming services.
Background services The default service is a background service, that is, the ONGOING Notification is not displayed in the Notification column. When the service is terminated, the user does not see the effect. Some services that do not require running or terminating prompts, such as weather updates, date synchronization, mail synchronization, etc.

Some students may ask, can we create an ONGOING Notification as a back-end service so that it becomes a front-end service? The answer is no. After doing the above work, the foreground service needs to call startForeground (Android 2.0 and later version) or setForeground (android 2.0 before version) to make the foreground service become the foreground service. The advantage of this approach is that ONGOING Notification will still be removed when the service is externally forced to terminate.

#### classified by usage

category The difference between
StartService Started service It is used to start a service to perform background tasks without communication. Stopping a service Use stopService
BindService Indicates the service to be started The services started by this method communicate. UnbindService is used to stop the service
StartService is also the service started by bindService StepService and unbindService should be used to stop the service

Special attention: 1. You should know that when you call bindService and bind it to Service, you should make sure that you call unbindService somewhere to unbind it (although the unbind will be unbound when the Activity is finished and the Service will stop automatically); You should use stopService to stop the service, whether you use bindService or not. UnbindService and stopService must be called at the same time to terminate the Service. Regardless of the call order of startService and bindService, if unbindService is called first, the service will not be terminated automatically, and then stopService will be stopped. If stopService is called first, the service will not be terminated. The service will stop only when unbindService is called again or the previous Context for calling bindService does not exist (e.g. when the Activity is finished). 4. When you rotate the phone screen, when the phone screen changes between “horizontal” and “vertical”, if your Activity automatically rotates, the rotation is actually a re-creation of the Activity. Therefore, the connection established with bindService before the rotation is broken (the Context does not exist) and the corresponding service has the same life cycle as above. 5, in SDK 2.0 and later versions, the corresponding onStart has been rejected to onStartCommand, but the previous onStart is still valid. This means that if you are developing an application using SDK 2.0 or later, you should use onStartCommand instead of onStart.

For details about the life cycles of the two startup modes, see Android Service Local Services

OnStartCommand,

When the startService method is called for the first time, the onCreate method and the onStartCommand method are called in sequence. When the startService method is called multiple times, only the onStartCommand method is called. Finally, we call the stopService method to stop the Service and the onDestory method is called back. This is the execution cycle of the Service in the started state. Intent Intent Intent flags int startId onStartCommand (Intent Intent Intent flags int startId)

  • Intent: An intent that is passed by the launching component when it is started. For example, an Activity can encapsulate the parameters required by the intent and pass them to a Service

  • Flags: indicates whether additional data is available when the request is started. Possible values are 0, START_FLAG_REDELIVERY, START_FLAG_RETRY, and 0 indicates none.

    • START_FLAG_REDELIVERY

    This value means that the onStartCommand method returns a value of START_REDELIVER_INTENT, and that the stopSelf method is called to stop the service before it was last killed. Where START_REDELIVER_INTENT means that when a Service is killed by the system due to lack of memory, the Service is rebuilt and onStartCommand() is called with the last Intent passed to the Service, in which case the Intent has a value.

    • START_FLAG_RETRY

    This flag indicates that onStartCommand() will be called again if no value is returned after onStartCommand is called.

  • StartId: indicates the unique ID of the current service. This ID is used together with stopSelfResult (int startId) to safely stop the service based on the ID.


Also, we notice that onStartCommand() returns a strange value, START_STICKY. What is this? Or what is the return value of this method used for? In fact, its return value is used to specify the system’s behavior toward the current thread. Its return value must be one of the following constants:

  • START_NOT_STICKY: If the system terminates the service after onStartCommand() returns, the system will not rebuild the service unless there is a pending Intent to deliver. This is the safest option to avoid running the service when it is not necessary and when the application can easily restart all outstanding jobs.

  • START_STICKY: If the system terminates the service after onStartCommand() returns, the service is rebuilt and onStartCommand() is called, but the last Intent is never redelivered. Instead, onStartCommand() is called with an empty Intent unless there is a pending Intent to start the service (in which case those intents will be delivered). This applies to media players (or similar services) that do not execute commands but run indefinitely and wait for jobs.

  • START_REDELIVER_INTENT: If the system terminates the service after onStartCommand() returns, the service is rebuilt and onStartCommand() is called with the last Intent passed to the service. Any pending intents are delivered in sequence. This applies to services that actively perform jobs that should be restored immediately, such as downloading files.

About the transition between starting services and binding services

Although a service can be in both started and bound states, a service can actually be in both states, that is, it can be either started (to run indefinitely) or bound. Note that the Android system only creates one instance object for each Service, so whether the Service is started or bound, the operation is the same Service instance, and the following two situations will occur due to the execution order of the binding Service or the startup Service:

  • If the current Service instance runs in the bound state and then in the started state, the bound Service will be converted to the started Service. If the previously bound host Activity is destroyed, the Service will continue to run. Specifies that the service will be destroyed only when a call to stop the service is received or when memory is low.

  • If the current Service instance runs first in the started state and then in the bound state, the currently started Service will not become a bound Service, but will still be bound to the host. Even after the host is unbound, the Service will continue to run in the background for the life cycle of the started Service. The service is not destroyed until either the Context calls stopService() or the service itself calls the stopSelf() method, or it runs out of memory.

The above two cases show that the starting service does have a higher priority than the binding service. However, whether a Service is started or bound, or started and bound, we can use the Service (even if the Service comes from another application) by invoking the Intent as we would with an Activity. Of course, we can also declare the service private through the manifest file, preventing other applications from accessing it. Last but not least, because the service runs in the main thread of its managed process (the UI thread), it neither creates its own thread nor runs in a separate process (unless otherwise specified). This means that if the service is going to perform any time-consuming event or blocking operation (such as MP3 playback or networking), a new thread should be created within the service to do the job; in short, the time-consuming operation should be executed in a separate thread. Only by using a separate thread can you reduce the risk of “application non-response” (ANR) errors so that the main thread of the application can focus on the interaction between the user and the Activity for a better user experience.

reference

Android Services: Silent Devotees (1)

Android Developers/Docs/ Guides/services

Comprehensive understanding of Service

Everything you need to know about what Android Services really are all about