Low-profile Service for Android Development

Source: Internet
Author: User

Low-profile Service for Android Development

Don't give up, don't fold; don't give up, don't give up. -- Condition

After learning about the usage of the Service today, I will discuss with you about the Service-related knowledge points in Android. If you have any mistakes, please criticize and correct them. If you have any questions, please leave a message.

I. Service Usage

The Service in Android and Activity belong to the same level of components. The Service in Android means "Service" and it cannot interact with each other in the background. The Service itself cannot run and needs to be called through an Activity or other Context object. The Context. startService () and Context. bindService () Methods start the Service. The Service in Android and Activity belong to the same level of components. The Service in Android means "Service", which runs in the background and cannot interact with each other. The Service itself cannot run and needs to be called through an Activity or other Context object. The Context. startService () and Context. bindService () Methods start the Service.
The service in Android is different from the Activity. It cannot interact with users, and cannot be started by itself. It runs programs in the background (focus on the work, but not even interfaces, so I said it is low-key.) If the Service process is still running in the background when we exit the application, when will we use the Service? For example, when we play music, we may want to listen to music and do other things. When we quit playing music, if we don't need Service, we won't be able to hear the song, so we need to use the Service at this time. For example, when the data of an application is obtained through the network, the data for different periods of time (a period of time) is different, at this time, we can use the Service to regularly update in the background, instead of getting it whenever the application is opened. If you perform some time-consuming actions in the onCreate or onStart method of the Service, it is best to start a new thread to run the Service, because if the Service runs in the main thread, it will affect the UI operation of the program or block other things in the main thread.

Ii. Service Lifecycle

First, let's take a look at the Service lifecycle diagram provided on the official website.

 

1. onCreate () create a Service
2. onStart (Intent intent, int startId) starts Service 3. onStartCommand (Intent intent, IntFlags, IntStartId) start the Service
4. onDestroy () destroy Service
5. onBind () returns an IBinder interface object to the Service
From the lifecycle graph, we can see two methods to start the Service: Context. startService and Context. bindService has two types of lifecycle: (1) startService startup mode. when startService (intent) is used, the system will instantiate a service and call the onCreate () and onStartCommand () methods in sequence. Then the Service enters the running status, if the service is already running, we will not re-create the service when we start it again. The system will automatically call the service we just started and call its onStart () method, if you want to destroy a service, you can use the stopService (intent) method. When you use the stopService () method, the onDestroy () method is called, and the service is destroyed,
(2) bindService start mode in this mode, bindService (Intent service, ServiceConnection conn, int flags) is called to bind a Service, then the Service will call its own onCreate () method (provided that the Service is not created), the system will instantiate a Service, and then call the onBind (intent) method to call the onBind method and then the caller can interact with the Service, when we use the bindService method to create a Service, the system will not create a new Service instance or call the onBind method if a Service has been created, the destroy method of the service started in this way is to use the unbindService method. At this time, both the onUnbind method and the onDestroy method are called. Description of the bindService (Intent service, ServiceConnection conn, int flags) parameters parameter ① service: Intent object parameter ② conn: ServiceConnection object to implement onServiceConnected () and onServiceDisconnected () handle the problem when the connection is successful or disconnected. The following example is used to describe the parameter ③ flags: Service creation method. Generally, Service. BIND_AUTO_CREATE is used to indicate automatic creation during binding.
Some may ask what are the differences between the two startup modes? The difference between strarService and bindService: In startService mode, the caller and service are not necessarily connected. Even if the caller ends his/her life cycle, the service will still run as long as the stopService method is not used to stop the service; however, in bindService mode, the service and the caller are both killed. After the binding is completed, the service will be terminated once the caller is destroyed. We usually use one sentence to describe bindService: you do not want to be born, but want to die together.
In addition, we used to rewrite the onStart method when we started the service using startService before Android2.0. In Android2.0, The onStartCommand method was introduced to replace the onStart method, but in order to be compatible with previous programs, in the onStartCommand method, the onStart method is actually called. We will perform verification later, but we 'd better rewrite the onStartCommand method.
Comrade Xiaoping once said that practice is the only criterion for testing truth. Next we will use examples to verify the above theory, so as to deepen the impression layout as follows:

 

 

The Code is as follows: 1. Service Code
package com.example.servicepractice;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;import android.util.Log;public class MyService extends Service {          private static final String TAG = MyService;     @Override     public void onCreate() {            super.onCreate();           Log. i(TAG,onCreate called );     }          @Override     public void onStart(Intent intent, int startId) {            super. onStart(intent, startId);           Log. i(TAG,onStart called );     }          @Override     public int onStartCommand(Intent intent, int flags, int startId) {           Log. i(TAG,onStartCommand called );            return super.onStartCommand(intent, flags, startId);     }          @Override     public void onDestroy() {            super.onDestroy();           Log. i(TAG,onDestroy called );     }          @Override     public IBinder onBind(Intent intent) {           Log. i(TAG,onBind called );            return null;     }          @Override     public boolean onUnbind(Intent intent) {           Log. i(TAG,onUnbind called );            return super.onUnbind(intent);     }}
2. MainActivity code
Package com. example. servicepractice; import android. OS. bundle; import android. OS. IBinder; import android. app. activity; import android. content. componentName; import android. content. context; import android. content. intent; import android. content. serviceConnection; import android. util. log; import android. view. menu; import android. view. view; import android. view. view. onClickListener; import android. view. viewGroup. layoutParams; import android. widget. button; public class MainActivity extends Activity {protected static final String TAG = MyService; private Button btn_start; private Button btn_stop; private Button btn_bind; private Button btn_unbind; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); findViews (); setClick ();} private void findViews () {btn_start = (Button) findViewById (R. id. btn_start); btn_stop = (Button) findViewById (R. id. btn_stop); btn_bind = (Button) findViewById (R. id. btn_bind); btn_unbind = (Button) findViewById (R. id. btn_unbind);} private void setClick () {// start the service btn_start.setOnClickListener (new OnClickListener () {public void onClick (View v) {Intent intent = new Intent (MainActivity. this, MyService. class); startService (intent) ;}}); // destroy service btn_stop.setOnClickListener (new OnClickListener () {public void onClick (View v) {Intent intent = new Intent (MainActivity. this, MyService. class); stopService (intent) ;}}); // bind the btn_bind.setOnClickListener (new OnClickListener () {public void onClick (View v) {Intent intent = new Intent (MainActivity. this, MyService. class); bindService (intent, conn, Context. BIND_AUTO_CREATE) ;}}); // unbind btn_unbind.setOnClickListener (new OnClickListener () {public void onClick (View v) {unbindService (conn );}});} private ServiceConnection conn = new ServiceConnection () {public void onServiceConnected (ComponentName, IBinder service) {// connected Log. I (TAG, onServiceConnection called .);} public void onServiceDisconnected (ComponentName name ){}};}

 

Because the service is one of the four major components, we need to configure it in the configuration file. Note: If the started service is not configured in the configuration file, no error will be reported (this error is hard to find, remember to configure), but the service is not started at startup, therefore, be sure to develop a good habit during Development ---> after the four components are declared, configure them; otherwise, it will take a long time to find the error configuration code if you forget it:

 

   
          
                                  
            
   
      
 

 

If our service is called only in this application, we can remove it. This attribute is the attribute configured when other applications call the services in this application. From the layout, we can see a total of four buttons. First, let's look at the first two buttons. 1. Start the service and destroy the service.
// Start the service btn_start.setOnClickListener (new OnClickListener () {public void onClick (View v) {Intent intent = new Intent (MainActivity. this, MyService. class); startService (intent) ;}}); // destroy service btn_stop.setOnClickListener (new OnClickListener () {public void onClick (View v) {Intent intent = new Intent (MainActivity. this, MyService. class); stopService (intent );}});
First, click the start button to print the log as follows:

 

We found that the order of the methods it calls is onCreate-> onStartCommand-> onStart. Then we click the Start Service button to print the result as follows:

 

We found that the system did not re-instantiate the Service when we started the Service again, because the system found that the Service has been started. At this time, it will directly call the onStartCommand method, and the onStart method will be called in the onStartCommand method.

Source code of the onStartCommand method:

     /* @param intent The Intent supplied to {@link android.content.Context#startService},     * as given.  This may be null if the service is being restarted after     * its process has gone away, and it had previously returned anything     * except {@link #START_STICKY_COMPATIBILITY}.     * @param flags Additional data about this start request.  Currently either     * 0, {@link #START_FLAG_REDELIVERY}, or {@link #START_FLAG_RETRY}.     * @param startId A unique integer representing this specific request to     * start.  Use with {@link #stopSelfResult(int)}.     *     * @return The return value indicates what semantics the system should     * use for the service's current started state.  It may be one of the     * constants associated with the {@link #START_CONTINUATION_MASK} bits.     *     * @see #stopSelfResult(int)     */    public int onStartCommand(Intent intent, int flags, int startId) {        onStart(intent , startId);        return mStartCompatibility ? START_STICKY_COMPATIBILITY : START_STICKY;    }
After the Start Service button is complete, click the destroy Service button to print the following logs:

 

It is found that when the stopService (intent) method is called, The onDestroy method of the Service is called to destroy the Service.

2. Learning to bind and unbind services

// Bind the btn_bind.setOnClickListener (new OnClickListener () {public void onClick (View v) {Intent intent = new Intent (MainActivity. this, MyService. class); bindService (intent, conn, Context. BIND_AUTO_CREATE) ;}}); // unbind btn_unbind.setOnClickListener (new OnClickListener () {public void onClick (View v) {unbindService (conn );}});
The preceding bindService (intent, conn, Context. BIND_AUTO_CREATEIn this method, we find that a ServiceConnection object is required. ServiceConnection represents the connection to the service. There are only two methods: onServiceConnected and onServiceDisconnected. The former is called when the operator successfully connects to a service, the latter is called when the connection is interrupted due to service crash or being killed, but it will not be called if we unbind ourselves, so we will only study the onServiceConnected method here.
Let's first look at the ServiceConnection code.
  private ServiceConnection conn= new ServiceConnection() {     /**     * Called when a connection to the Service has been established, with     * the {@link android.os.IBinder} of the communication channel to the     * Service.     *     * @param name The concrete component name of the service that has     * been connected.     *     * @param service The IBinder of the Service's communication channel,     * which you can now make calls on.     */       public void onServiceConnected(ComponentName name, IBinder service) {                 //connected                Log. i( TAG,onServiceConnection called. );           }          /**     * Called when a connection to the Service has been lost.  This typically     * happens when the process hosting the service has crashed or been killed.     * This does not  remove the ServiceConnection itself -- this     * binding to the service will remain active, and you will receive a call     * to {@link #onServiceConnected} when the Service is next running.     *     * @param name The concrete component name of the service whose     * connection has been lost.     */      public void onServiceDisconnected(ComponentName name) {                }};
At this point, we can bind the service only one step away, because the onBind method returned value in the previous service is null, which is not acceptable. To implement the binding operation, an instance that implements the IBinder interface type must be returned. This interface describes the abstract protocol for interaction with remote objects. With this interface, we can interact with the service. So we need to modify the code.
     @Override     public IBinder onBind(Intent intent) {           Log. i(TAG,onBind called );            return new Binder(){};     }
The code above returns a Binder instance, which implements the IBinder interface, so you can bind the service.

 

First, click the "bind Service" button to print the log as follows. We found that the onCreate method, onBind method, and onServiceConnection method were called, and the service is running, if we click "bind Service" again, none of the three methods will be called and then click "Unbind" to print the following log. We can see that the onUnbind method and onDestroy method are called, the Service has been destroyed and the entire lifecycle ends. Because the service started by bindService is bound with the application, the service ends when MainActivity exits the program. The following is a case where, when we click the bind Service button, we click the "Unbind" button twice to find that the program crashes. The log is as follows, when we click "bind service", the service is running. At this time, we press "return" to exit the program. An error is reported in the log.
To solve these two problems, we can define a variable and unbind it from the onDestroy method of the Activity, that is, make the following changes.
// Define a variable to identify whether the service is in the BIND State private boolean binded; // define a method for binding the service private void unbindService () {if (binded) {unbindService (conn); binded = false ;}}// unbind btn_unbind.setOnClickListener (new OnClickListener () {public void onClick (View v) {unbindService ();}}); // call the unbind method in the onDestroy method protected void onDestroy () {unbindService ();};
In this way, the above two errors are solved, which also reflects the rigor of code writing. 

3. the above two startup methods use a mix of learning methods. We have discussed a pair of matching startup and destruction methods. Some may ask, what will happen if I click these four buttons in a mix? Then let's verify that we click the Start Service button to print the following logs, which is no problem with the matching we discussed earlier, then, press the bind Service button to print the log as follows:
After the onBind method is called, we click the unbind button. The log is as follows:

At this time, the onUbind method is called. It is worth noting that although the service is removed but not terminated, it continues to run, then we click the bind Service button and unbind Service button again to find that the onbind and onUnbind methods are not called. Is the binding successful? The answer is that although the onBind method is not called, the binding is still successful. We can verify it from the following log:


But how can we destroy this service? The answer is: if we use both startService and bindService, the Service must be called at the same time by unbindService and stopService to terminate the Service, regardless of the call sequence between startService and bindServicede, 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 that previously called bindService is no longer available (for example, when the Activity is finished;

Summary + Special notes:

1. When bindService is called and bound to the 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 you start the service using startService, you must stop the service using stopService, 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.

6. startService 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.

 

 

 



 

 

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.