Detailed introduction to methods in Android Service
Detailed introduction to methods in Android Service
In Android, Activity is mainly responsible for displaying front-end pages, and Service is mainly responsible for tasks that require long-term operation. For example, a music player playing music from the service should be set to run at the front end, because the user will pay attention to its operation. the notification in the status bar may display the current song and allow the user to start an activity to interact with the music player.
Service implementation
1. Not bound
Call the startService () method of an Application Component (such as Activity) to start a service. once started, the service will always run in the background, even if the application components are closed at this time. generally, a started service processes some single functions and does not need to return results to the caller. for example, download or upload a file on the network. the service is closed only when the service is finished.
2. bind)
BindService () method of the application component is called to bind a service. the Bound Service provides a client-server interaction interface. this interface is mainly used to interact with applications, send requests, obtain results, and even access processes through IPC. as long as a program component is bound to a service, the binding service will run. Multiple application components can be bound to a service at the same time. when all application components are unbound, the bound server is destroyed.
Introduction to service implementation methods
OnStartCommand ()
The system calls this method when other components, such as activity, call startService () to request service startup. once this method is executed, the service starts and runs in the background for a long time. if you implement it, you need to stop the service when it completes the task by calling stopSelf () or stopService (). (If you only want to provide binding, you do not need to implement this method ).
OnBind ()
The system calls this method when the component calls bindService () and wants to bind it to the service (for example, to execute inter-process communication. in your implementation, you must provide an IBinder for the client to communicate with the service. You must always implement this method, but if you do not allow binding, then you should return null.
OnCreate ()
The system executes this method when the service is created for the first time to execute initialization only once (before calling the method such as onStartCommand () or onBind ). if the service is already running, this method will not be called.
OnDestroy ()
This method is called when the service is no longer in use and is to be destroyed. your service should release resources in this method, such as threads, registered listeners, and receivers. this is the last call received by the service.
If a component starts a service by calling startService (), the service will continue to run until it passes stopSelf () stop yourself or other components call stopService () to stop it.
Service implementation code
1. Not bound
Create a new MyService that inherits from the Service and override the onCreate (), onStartCommand (), and onDestroy () Methods of the parent class.
?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 |
Public class MyIntentService extends IntentService {
Public MyIntentService (){
Super ("MyIntentService ");
}
@ Override
Protected void onHandleIntent (Intent intent ){
// IntentService uses a separate thread to execute the code of this method.
// Execute time-consuming tasks in this method, such as downloading files. The thread is only waiting for 20 seconds.
Long endTime = System. currentTimeMillis () + 20*1000;
System. out. println ("onStart ");
While (System. currentTimeMillis () <endTime ){
Synchronized (this ){
Try {
Wait (endTime-System. currentTimeMillis ());
} Catch (InterruptedException e ){
E. printStackTrace ();
}
}
}
System. out. println ("---- time-consuming task execution completed ---");
}
}
|
We added two buttons to the layout file, one for starting the Service and the other for stopping the Service.
Then open or create a MainActivity as the main Activity of the program, and add the logic of starting and stopping the Service in it. The Code is as follows:
?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 |
Public class MainActivity extends Activity implements OnClickListener {
Private Button startService;
Private Button stopService;
@ Override
Protected void onCreate (Bundle savedInstanceState ){
Super. onCreate (savedInstanceState );
SetContentView (R. layout. activity_main );
StartService = (Button) findViewById (R. id. start_service );
StopService = (Button) findViewById (R. id. stop_service );
StartService. setOnClickListener (this );
StopService. setOnClickListener (this );
}
@ Override
Public void onClick (View v ){
Switch (v. getId ()){
Case R. id. start_service:
Intent startIntent = new Intent (this, MyService. class );
StartService (startIntent );
Break;
Case R. id. stop_service:
Intent stopIntent = new Intent (this, MyService. class );
StopService (stopIntent );
Break;
Default:
Break;
}
}
|
Every Service in the project must be registered in AndroidManifest. xml. Therefore, you also need to edit the AndroidManifest. xml file. The Code is as follows:
?
|
1
2
3
4
5
6
7
8
9 |
<Application
Android: allowBackup = "true"
Android: icon = "@ drawable/ic_launcher"
Android: label = "@ string/app_name"
Android: theme = "@ style/AppTheme">
......
<Service android: name = "com. example. servicetest. MyService">
</Service>
</Application>
|
Periodic analysis
The onCreate () method is called only when the Service is created for the first time. If the current Service has been created, call the startService () method, onCreate () method will not be executed. Therefore, you can click the Start Service button several more times to try again. Each time, only the printing logs in the onStartCommand () method are displayed.
2. Bound service
?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 |
Public class LocalService extends Service {
// Binder given to clients
Private final IBinder mBinder = new LocalBinder ();
// Random number generator
Private final Random mGenerator = new Random ();
Public class LocalBinder extends Binder {
LocalService getService (){
// Return the instance of this service to the client, so the client can call the public method of this service
Return LocalService. this;
}
}
@ Override
Public IBinder onBind (Intent intent ){
Return mBinder;
}
/** Method to be called by the client */
Public int getRandomNumber (){
Return mGenerator. nextInt (100 );
}
}
|
The following is an example of actvity that is bound to LocalService and called getRandomNumber () when the button is pressed:
?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 |
Public class BindingActivity extends Activity {
LocalService mService;
Boolean mBound = false;
@ Override
Protected void onCreate (Bundle savedInstanceState ){
Super. onCreate (savedInstanceState );
SetContentView (R. layout. main );
}
@ Override
Protected void onStart (){
Super. onStart ();
// Bind the instance to a class LocalService
Intent intent = new Intent (this, LocalService. class );
BindService (intent, mConnection, Context. BIND_AUTO_CREATE );
}
@ Override
Protected void onStop (){
Super. onStop ();
// Unbind from service
If (mBound ){
UnbindService (mConnection );
MBound = false;
}
}
/** Call when the button is pressed (the button defined in the layout file uses the android: onClick attribute to specify the response to this method )*/
Public void onButtonClick (View v ){
If (mBound ){
// Call a method of LocalService
// However, if a pending operation exists in this call, the request should be sent
// Avoid downloading activity performance in another thread.
Int num = mService. getRandomNumber ();
Toast. makeText (this, "number:" + num, Toast. LENGTH_SHORT). show ();
}
}
/** Define the callback bound to the service and pass it to bindService */
Private ServiceConnection mConnection = new ServiceConnection (){
@ Override
Public void onServiceConnected (ComponentName className,
IBinder service ){
// We have already bound to LocalService, and forced type conversion for IBinder and obtaining the LocalService instance.
LocalBinder binder = (LocalBinder) service;
MService = binder. getService ();
MBound = true;
}
@ Override
Public void onServiceDisconnected (ComponentName arg0 ){
MBound = false;
}
};
}
|
Service Periodic Functions
1. When the Context. startService () method is used to start the service, the related lifecycle Method
OnCreate ()-> onStart ()-> onDestroy ()
OnCreate () This method is called when a service is created. This method is called only once. No matter how many times the startService () or bindService () method is called, the service is created only once.
OnStart () calls back this method only when the Context. startService () method is used to start the service. This method is called when the service starts running. Although the startService () method is called multiple times, the onStart () method is called multiple times.
OnDestroy () is called when the service is terminated.
2. When the Context. bindService () method is used to start the service, the related lifecycle Method
OnCreate ()-> onBind ()-> onUnbind ()-> onDestroy ()
OnBind () calls back this method only when the Context. bindService () method is used to start the service. This method is called when the caller binds to the service. When the caller and the service are already bound, multiple calls to the Context. bindService () method will not cause this method to be called multiple times.
OnUnbind () calls back this method only when the Context. bindService () method is used to start the service. This method is called when the caller and the service are unbound.
If you use the startService () method to start the service, then call the bindService () method to bind to the service, then call the unbindService () method to unbind, and finally call the bindService () method to bind to the service again, the method for triggering the lifecycle is as follows:
OnCreate ()-> onStart ()-> onBind ()-> onUnbind () [true must be returned for the overloaded method-> onRebind ()
So what if we click both the Start Service button and the Bind Service button?
At this time, you will find that the Service will not be destroyed whether you click the Stop Service button or the Unbind Service button separately. You must click both buttons to destroy the Service. That is to say, clicking the Stop Service button will only Stop the Service, and clicking the Unbind Service button will only disassociate the Service from the Activity, A Service must be destroyed only when it is not associated with any Activity and is in the stopped state.
Difference between Service and Thread
This is mainly because of the background concept of the Service. Thread we all know that it is used to start a sub-Thread. If you perform some time-consuming operations here, the main Thread will not be blocked. When we first understood the Service, we always thought it was used to process some background tasks, and some time-consuming operations can also be run here, which can be confusing. However, if I tell you that the Service is actually running in the main thread, it does not matter.
What is the use of the Service?
In fact, you can't associate the backend with the sub-thread. This is a completely different concept.
The Android background means that its operation is completely independent of the UI. Even if the Activity is destroyed or the program is closed, the Service can continue to run as long as the process is still running.
For example, some applications always need to maintain a heartbeat connection with the server, and can be implemented using the Service. You may ask again, didn't you just verify that the Service is running in the main thread? The heartbeat connection is always executed here. Won't the main thread be blocked? Yes, of course, but we can create another sub-thread in the Service and then process the time-consuming logic here.
Difference between using service to create a thread and using activity to directly create a thread
It is difficult for the Activity to control the Thread. After the Activity is destroyed, there is no other way to re-obtain the instance of the previously created sub-Thread. In addition, the sub-thread created in one Activity cannot be operated on by another Activity. But the Service is different. All the activities can be associated with the Service, and then the methods can be easily operated. Even if the Activity is destroyed, you only need to establish a new association with the Service, then you can get the Binder instance in the original Service. Therefore, if you use the Service to process Background tasks, the Activity can be safely completed without worrying about the inability to control background tasks.
IntentService Introduction
IntentService is a subclass of a Service, which provides additional functions than a common Service.
First, there are two problems with the Service itself:
The Service does not start a separate process. The Service and its application are in the same process;
The Service is not a new thread, so it is not necessary to directly process time-consuming tasks in the Service;
Ii. IntentService features
An independent worker thread is created to process all Intent requests;
An independent worker thread is created to process the Code implemented by the onHandleIntent () method, without the need to handle multithreading issues;
After all requests are processed, IntentService automatically stops without calling the stopSelf () method;
Provides default implementation for the onBind () of the Service, and returns null;
Provides the default implementation for the onStartCommand of the Service, and adds the request Intent to the queue;
Implementation
?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 |
Public class MyIntentService extends IntentService {
Public MyIntentService (){
Super ("MyIntentService ");
}
@ Override
Protected void onHandleIntent (Intent intent ){
// IntentService uses a separate thread to execute the code of this method.
// Execute time-consuming tasks in this method, such as downloading files. The thread is only waiting for 20 seconds.
Long endTime = System. currentTimeMillis () + 20*1000;
System. out. println ("onStart ");
While (System. currentTimeMillis () <endTime ){
Synchronized (this ){
Try {
Wait (endTime-System. currentTimeMillis ());
} Catch (InterruptedException e ){
E. printStackTrace ();
}
}
}
System. out. println ("---- time-consuming task execution completed ---");
}
}
|
Activity Code
?
|
1
2
3
4
5 |
Public void startIntentService (View source ){
// Create the Intent of the IntentService to be started
Intent intent = new Intent (this, MyIntentService. class );
StartService (intent );
|