Comprehensive summary of services in Android

Source: Internet
Author: User

1. Service Type
By location:
Category Differences Advantages Disadvantages Application
Local) The service is attached to the main process, Services are attached to the main process rather than independent processes, which saves resources to some extent. In addition, the Local service does not require IPC or AIDL because it is in the same process. BindService is much more convenient. After the master process is killed, the service is terminated. Very common applications such as HTC's music play service and the music play service every day.
Remote services) This service is an independent process, The service is an independent process. The corresponding process name format is the package name plus the android: process string you specified. Because it is an independent process, when the process of the Activity is killed, the service is still running and is not affected by other processes. Therefore, it is helpful to provide services for multiple processes with high flexibility. This service is an independent process that occupies a certain amount of resources, and it is a little troublesome to use AIDL for IPC. Some services that provide system services are resident.

In fact, remote services are rare and generally system services.
By running type:

Category Differences Application
Front-End Service The ONGOING Notification is displayed in the Notification column, When the service is terminated, the Notification in the Notification column disappears, which has a certain effect on the user. This is a common music play service.
Background Service The default service is the background service, that is, the ONGOING Notification is not displayed in the Notification column. When the service is terminated, the user cannot see the effect. Some services that do not need to run or stop prompts, such as weather updates, date synchronization, and email synchronization.

Some may ask, can we create an ONGOING Notification in the background service to become a front-end service? The answer is no. The front-end service must call startForeground (android 2.0 and later versions) or setForeground (versions earlier than android 2.0) to make the service a front-end service. The advantage of this is that when the service is forcibly terminated by the outside, the ONGOING Notification will be removed.
Categories by usage:

Category Differences
StartService It is mainly used to start a service to execute background tasks without communication. Stop a service use stopService
Services started by bindService Services started by this method need to communicate. Stop services use unbindService
StartService is also a service started by bindService StepService and unbindService should be used to stop the service at the same time.

The life cycle of the services started in the above three methods is also different, which will be given later.
2. Differences between services and threads
In many cases, you may ask why we need to use a Service instead of a Thread, because it is convenient to use a Thread, which is much more convenient than a Service. I will explain it in detail below.
1). Thread: Thread is the minimum unit for program execution. It is the basic unit for CPU allocation. You can use Thread to perform some asynchronous operations.
2). Service: A mechanism of android. If it is a Local Service during running, the corresponding Service runs on the main thread of the main process. For example, onCreate and onStart functions run on the main thread of the main process when called by the system. For Remote Service, the corresponding Service runs on the main thread of the independent process. Therefore, do not regard the Service as a thread. It has nothing to do with the thread's half dime!

In this case, why should we use the Service? In fact, this is related to the android system mechanism. Let's talk about Thread first. The running of Thread is independent from the Activity. That is to say, after an Activity is finished, if you do not stop the Thread actively or the run method in the Thread is not completed, the Thread will continue to be executed. Therefore, a problem occurs: after the Activity is finished, you no longer hold the reference of this Thread. On the other hand, you cannot control the same Thread in different activities.

For example: If your Thread needs to connect to the server for some synchronization after a period of time, the Thread must also run when the Activity does not start. At this time, when you start an Activity, you cannot control the previously created Thread in the Activity. Therefore, you need to create and start a Service, create, run, and control the Thread in the Service to solve this problem (because any Activity can control the same Service, and the system will only create one corresponding Service instance ).

Therefore, you can think of a Service as a message Service, and you can call Context wherever Context exists. startService, Context. stopService, Context. bindService, Context. unbindService, to control it. You can also register BroadcastReceiver in the Service and control it by sending broadcast elsewhere. Of course, none of these can be done by Thread.
3. Service Lifecycle
OnCreate onStart onDestroy onBind
1 ). life cycle of the started Service: If a Service is called by an Activity, Context. start the startService method. No matter whether any Activity is bound to bindService or unbindService is unbound from the Service, the Service runs in the background. If a Service is started multiple times by the startService method, the onCreate method is called only once, and the onStart method is called multiple times (corresponding to the number of times startService is called ), in addition, the system will only create one Service instance (so you should know that only one stopService call is required ). The Service will always run in the background, regardless of whether the Activity of the corresponding program is running until it is called stopService or its own stopSelf method. Of course, if the system resources are insufficient, the android system may also end the service.

2 ). the lifecycle of the bound Service: If a Service is called by an Activity, Context. bindService method binding starts. No matter how many times bindService is called, The onCreate method is called only once, and the onStart method is never called. After the connection is established, the Service will continue to run unless Context is called. if the unbindService is disconnected or the Context of the previously called bindService does not exist (for example, when the Activity is finished), the system automatically stops the Service and the onDestroy is called.

3). lifecycle of the started and bound Service: If a Service is started and bound, the Service will always run in the background. In addition, no matter how it is called, onCreate will always be called once, and the number of times corresponding to startService is called, The onStart of Service will be called several times. Calling unbindService does not stop the Service, but must call stopService or Service stopSelf to stop the Service.

4 ). when the Service is stopped, clear the Service: when a Service is terminated (1. stopService is called; 2. stopSelf is called; 3. No bound connections (not started) exist, the onDestroy method will be called. here you should do some cleanup work, such as stopping the thread created and running in the Service.
Special note:
1. You should know that when calling bindService to bind to Service, you should ensure that unbindService is called somewhere to unbind (although the binding will be automatically released when the Activity is finished, and the Service will automatically stop );
2. After starting the service using startService, you must use stopService to stop the service, whether or not you use bindService;
3. When using both startService and bindService, you must note that the termination of the Service requires both unbindService and stopService to terminate the Service, regardless of the Call Sequence of startService and bindService, if the unbindService is called first, the service will not be automatically terminated at this time, and then the service will be stopped after the stopService is called. If the stopService is called first, the service will not be terminated at this time, the Service stops automatically after unbindService is called or the Context of bindService is called does not exist (for example, when the Activity is finished;
4. When the mobile phone screen is being rotated, if your Activity is automatically rotated when the mobile phone screen is being "horizontal" or "vertical, the rotation is actually a re-creation of the Activity, so the connection established using bindService before the rotation will be disconnected (the Context does not exist), and the corresponding service life cycle is the same as above.
5. In sdk 2.0 and later versions, the corresponding onStart has been denied and changed to onStartCommand, but the previous onStart is still valid. This means that if the sdk for your developed application is 2.0 or later, you should use onStartCommand instead of onStart.
4. startService starts the service.
To start the service with startService, the work we need to do is as simple as Local or Remote. Of course, remember to register the service in Androidmanifest. xml.
Based on the above lifecycle, we will provide the code framework in the Service:Copy codeThe Code is as follows: package com. newcj. test;
Import android. app. Service;
Import android. content. Intent;
Import android. OS. IBinder;
Public class LocalService1 extends Service {
/**
* OnBind is a virtual method of Service, so we have to implement it.
* Return null, indicating that the customer service cannot establish a connection to this service.
*/
@ Override
Public IBinder onBind (Intent intent ){
Return null;
}
@ Override
Public void onCreate (){
Super. onCreate ();
}
@ Override
Public void onStart (Intent intent, int startId ){
Super. onStart (intent, startId );
}
@ Override
Public void onDestroy (){
Super. onDestroy ();
}
}

Copy codeThe Code is as follows: // start an Activity
StartActivity (new Intent (this, LocalService1.class ));
...
// Stop an Activity
StopService (new Intent (this, LocalService1.class ));

The corresponding Intent is the Intent of the Flag service class.
5. Local and Remote service binding
Also remember to Register service in Androidmanifest. xml
1). Local Service binding: the Local Service binding is relatively simple. First, we need to implement the Service's abstract method onBind in the Service and return an object that implements the IBinder interface.
Service Code:Copy codeThe Code is as follows: package com. newcj. test;
Import android. app. Service;
Import android. content. Intent;
Import android. OS. Binder;
Import android. OS. IBinder;
Public class LocalService extends Service {
/**
* In the Local Service, we directly inherit the Binder instead of IBinder, because the Binder implements the IBinder interface, so we can do less work.
* @ Author newcj
*/
Public class SimpleBinder extends Binder {
/**
* Getting a Service instance
* @ Return
*/
Public LocalService getService (){
Return LocalService. this;
}
Public int add (int a, int B ){
Return a + B;
}
}
Public SimpleBinder sBinder;
@ Override
Public void onCreate (){
Super. onCreate ();
// Create SimpleBinder
SBinder = new SimpleBinder ();
}
@ Override
Public IBinder onBind (Intent intent ){
// Returns the SimpleBinder object
Return sBinder;
}
}

The key to the code above is that the onBind (Intent) method returns an object that implements the IBinder interface. This object will be used to bind the Service Activity to communicate with the Local Service. The code in the Activity is as follows:Copy codeThe Code is as follows: package com. newcj. test;
Import android. app. Activity;
Import android. content. ComponentName;
Import android. content. Context;
Import android. content. Intent;
Import android. content. ServiceConnection;
Import android. OS. Bundle;
Import android. OS. IBinder;
Import android. util. Log;
Import android. view. View;
Import android. view. View. OnClickListener;
Public class Main extends Activity {
Private final static String TAG = "SERVICE_TEST ";
Private ServiceConnection SC;
Private boolean isBind;
@ Override
Public void onCreate (Bundle savedInstanceState ){
Super. onCreate (savedInstanceState );
SetContentView (R. layout. main );
SC = new ServiceConnection (){
@ Override
Public void onServiceDisconnected (ComponentName name ){
}
@ Override
Public void onServiceConnected (ComponentName name, IBinder service ){
LocalService. SimpleBinder sBinder = (LocalService. SimpleBinder) service;
Log. v (TAG, "3 + 5 =" + sBinder. add (3, 5 ));
Log. v (TAG, sBinder. getService (). toString ());
}
};
FindViewById (R. id. btnBind). setOnClickListener (new OnClickListener (){
@ Override
Public void onClick (View v ){
BindService (new Intent (Main. this, LocalService. class), SC, Context. BIND_AUTO_CREATE );
IsBind = true;
}
});
FindViewById (R. id. btnUnbind). setOnClickListener (new OnClickListener (){
@ Override
Public void onClick (View v ){
If (isBind ){
UnbindService (SC );
IsBind = false;
}
}
});
}
}

In Activity, we use the ServiceConnection interface to obtain the callback for accidental loss of connection establishment and connection. BindService has three parameters. The first parameter is used to distinguish the Intent of the Service from the Intent in startService. The second parameter is the object that implements the ServiceConnection interface, and the last parameter is the flag. There are two flags: BIND_DEBUG_UNBIND and BIND_AUTO_CREATE. The former is used for debugging. (For details, see the javadoc description.) the latter is used by default. UnbindService unbinds, and the parameter is the previously created ServiceConnection interface object. In addition, multiple calls to unbindService to release the same connection throws an exception. Therefore, I created a boolean variable to determine whether unbindService has been called.
Running result:

2) Remote service binding: Remote service binding requires the android IPC Mechanism because the service is in another process. This will be a very long topic. Therefore, I plan to write another analysis on the android IPC Mechanism and describe it in detail. Then, I will update the link here. Stay tuned.
Note:
1. Service. if onBind returns null, calling bindService will start the Service, but will not connect to the Service. Therefore, ServiceConnection. onServiceConnected will not be called, but you still need to use the unbindService function to disconnect it so that the Service will stop.
6. Create a front-end service
The advantages of the front-end service have been described above, but the service is set as the front-end service. We need to note that the methods used in sdk 2.0 and later versions are startForeground and stopForeground. The previous versions use setForeground, therefore, if your application requires a minimum runtime environment of 2.0, you can directly use the new method here. If the runtime environment is less than 2.0, in order to ensure backward compatibility, reflection technology must be used to call a new method.
The following is the code I re-typed on ApiDemos and modified some places, so it is more descriptive:Copy codeThe Code is as follows: package com. newcj. test;
Import java. lang. reflect. InvocationTargetException;
Import java. lang. reflect. Method;
Import android. app. Notification;
Import android. app. icationicationmanager;
Import android. app. PendingIntent;
Import android. app. Service;
Import android. content. Context;
Import android. content. Intent;
Import android. OS. IBinder;
Public class ForegroundService extends Service {
Private static final Class [] mStartForegroundSignature = new Class [] {
Int. class, Notification. class };
Private static final Class [] mStopForegroundSignature = new Class [] {
Boolean. class };
Private icationicationmanager mNM;
Private Method mStartForeground;
Private Method mStopForeground;
Private Object [] mStartForegroundArgs = new Object [2];
Private Object [] mStopForegroundArgs = new Object [1];
@ Override
Public IBinder onBind (Intent intent ){
Return null;
}
@ Override
Public void onCreate (){
Super. onCreate ();
MNM = (icationicationmanager) getSystemService (Context. NOTIFICATION_SERVICE );
Try {
MStartForeground = ForegroundService. class. getMethod ("startForeground", mStartForegroundSignature );
MStopForeground = ForegroundService. class. getMethod ("stopForeground", mStopForegroundSignature );
} Catch (NoSuchMethodException e ){
MStartForeground = mStopForeground = null;
}
// We do not need to set FLAG_ONGOING_EVENT for notification. flags because
// The notification. flags of the foreground service always contains the flag by default.
Notification notification = new Notification (R. drawable. icon, "Foreground Service Started .",
System. currentTimeMillis ());
PendingIntent contentIntent = PendingIntent. getActivity (this, 0,
New Intent (this, Main. class), 0 );
Notification. setLatestEventInfo (this, "Foreground Service ",
"Foreground Service Started.", contentIntent );
// Use startForeground. If the id is 0, the notification is not displayed.
StartForegroundCompat (1, notification );
}
@ Override
Public void onDestroy (){
Super. onDestroy ();
StopForegroundCompat (1 );
}
// Start the front-end service in compatibility mode
Private void startForegroundCompat (int id, Notification n ){
If (mStartForeground! = Null ){
MStartForegroundArgs [0] = id;
MStartForegroundArgs [1] = n;
Try {
MStartForeground. invoke (this, mStartForegroundArgs );
} Catch (IllegalArgumentException e ){
E. printStackTrace ();
} Catch (IllegalAccessException e ){
E. printStackTrace ();
} Catch (InvocationTargetException e ){
E. printStackTrace ();
}
Return;
}
SetForeground (true );
MNM. notify (id, n );
}
// Disable the front-end service in compatibility mode
Private void stopForegroundCompat (int id ){
If (mStopForeground! = Null ){
MStopForegroundArgs [0] = Boolean. TRUE;
Try {
MStopForeground. invoke (this, mStopForegroundArgs );
} Catch (IllegalArgumentException e ){
E. printStackTrace ();
} Catch (IllegalAccessException e ){
E. printStackTrace ();
} Catch (InvocationTargetException e ){
E. printStackTrace ();
}
Return;
}
// Call cancel before setForeground, because it is possible that after the front-end service is canceled
// Is killed at that moment. At this time, the notification will never be removed from the notification column.
MNM. cancel (id );
SetForeground (false );
}
}

Special note: 1. Use startForeground. If the id is 0, the notification will not be displayed.
7. When to use startService or bindServiceOr use startService and bindService at the same time.
If you only want to start a background service for a long time for a task, you can use startService. If you want to contact a running Service, you can use either broadcast or bindService. The disadvantage of the former is that if communication is frequent, it is easy to cause performance problems, and BroadcastReceiver itself executes the code for a short period of time (maybe half of the Code will not be executed later), while the latter does not, therefore, we certainly choose to use bindService (at this time, you are using startService and bindService at the same time, which is quite useful to update some running states of the Service in the Activity ). In addition, if your Service only exposes a remote interface, you can remotely call the execution method on the connected client (the android Service is in the C/S architecture. At this time, you can not let the service run at the beginning, but only bindService, so that the first bindService will create a service instance to run it, which will save a lot of system resources, especially if your Service is a Remote Service, the more obvious the effect will be (of course, it will take some time to create the Service, you should note this ).
8. Common options of Service elements in AndroidManifest. xml
Android: name ------------- service class name
Android: label -------------- service name. If this item is not set, the default displayed service name is the class name.
Android: icon -------------- Service icon
Android: permission ------- declares the permissions of this service, which means that only applications that provide this permission can control or connect to this service.
Android: process ---------- indicates whether the service is running in another process. If this option is set, this string is added after the package name to indicate the name of another process.
Android: enabled ---------- if this option is set to true, the Service will be started by default. If this option is not set, the default value is false.
Android: exported --------- indicates whether the service can be controlled or connected by other applications. If this parameter is not set, the default value is false.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.