Android Service fully resolves everything you need to know about the service (on)

Source: Internet
Author: User

Source: http://blog.csdn.net/guolin_blog/article/details/11952435

I believe most of my friends are not unfamiliar with the term service, yes, a seasoned Android programmer who has not even heard of the service is really lame. Service as one of the four components of Android, plays a very important role in every application. It is used primarily to process time-consuming logic in the background, or to perform certain tasks that require long-term operation. When necessary, we can even leave the service running in the background in case the program exits.

However, although the service is almost familiar to every Android programmer, not everyone has mastered the knowledge points of the service very thoroughly. So today I will take you to a comprehensive, in-depth exploration of the service, I hope that everyone after reading this article can have a deeper understanding of the service.

basic usage of service  

The basic usage of service is how to start a service, the way to start the service and start the activity is very similar, all need to use intent to achieve, below we have a specific example to look at.

Create a new Android project, the project name is called Servicetest, here I choose to use the 4.0 API.

Then create a new myservice that inherits from the service and overrides the parent class's OnCreate (), Onstartcommand (), and OnDestroy () methods as follows:

public class MyService extends Service {public        static final String TAG = "MyService";        @Override public      void OnCreate () {          super.oncreate ();          LOG.D (TAG, "onCreate () executed");      }        @Override public      int Onstartcommand (Intent Intent, int flags, int startid) {          log.d (TAG, "Onstartcommand () Executed ");          Return Super.onstartcommand (Intent, flags, Startid);      }            @Override public      void OnDestroy () {          Super.ondestroy ();          LOG.D (TAG, "OnDestroy () executed");      }        @Override public      IBinder onbind (Intent Intent) {          return null;      }    

As you can see, we just printed a single word in the OnCreate (), Onstartcommand (), and OnDestroy () methods, and didn't do anything else.

Then open or create a new activity_main.xml as the main layout file for your program, as shown in the following code:

<linearlayout xmlns:android= "http://schemas.android.com/apk/res/android"      android:layout_width= "Match_ Parent "      android:layout_height=" match_parent "      android:orientation=" vertical ">        <button          Android:id= "@+id/start_service"          android:layout_width= "match_parent"          android:layout_height= "Wrap_ Content "          android:text=" Start Service "/>        <button          android:id=" @+id/stop_service "          android: Layout_width= "Match_parent"          android:layout_height= "wrap_content"          android:text= "Stop Service"/>    </LinearLayout>  

We have added two buttons to the layout file, one for starting the service and one for stopping the service.

Then open or create a new mainactivity as the main activity of the program, add the logic to start the service and stop the service, the code is as follows:

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 ()) {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;  }    }    } 

As you can see, in the Click event of the Start Service button, we built a intent object and called the StartService () method to start the MyService. Then, in the click event of the Stop Serivce button, we also built a intent object and called the StopService () method to stop the MyService. The logic of the code is very simple, I believe I do not need to explain more.

It is also important to note that each service in the project must be registered in Androidmanifest.xml, so the Androidmanifest.xml file needs to be edited, as shown in the following code:

<?xml version= "1.0" encoding= "Utf-8"?> <manifest  xmlns:android= "http://schemas.android.com/apk/res/ Android "      package=" com.example.servicetest "      android:versioncode=" 1 "      android:versionname=" 1.0 ">        <uses-sdk          android:minsdkversion= "android:targetsdkversion="          />        <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 >    

In this case, a simple program with service function is written, now we run the program, and click on the Start Service button, you can see the Logcat print log as follows:

That is, when a service is started, the OnCreate () and Onstartcommand () methods in the service are called.

So what if I click the Start service button again? This time the print log is as follows:

As you can see, this time only the Onstartcommand () method is executed, and the OnCreate () method is not executed. This is because the OnCreate () method is only called when the service is first created, and if the current service has already been created, the OnCreate () method will no longer execute if the StartService () method is called. So you can click the Start Service button a few more times to try again, each time there will only be a print log in the Onstartcommand () method.

We can also check the phone's application management interface to see if MyService is running, as shown in:

Well, MyService is really running, even if it's not performing any logic inside.

Go back to the Servicetest program and click the Stop Service button to stop the MyService.

Service and Activity Communication

Above we learned the basic usage of service, after starting the service, we can execute some concrete logic in the OnCreate () or Onstartcommand () method. However, the service and activity of the relationship is not big, but the activity notified the service: "You can start up." Then the service went on with his own business. So is there any way to make them more relevant? In activity, for example, you can specify what tasks the service performs. Of course, just let the activity and the service be related.

Observing the code in MyService, you will find that there is always a onbind () method that we are not using, and this method is actually used to correlate with the activity and modify the code in MyService as follows:

public class MyService extends Service {public static final String TAG = "MyS        Ervice ";        Private Mybinder Mbinder = new Mybinder ();          @Override public void OnCreate () {super.oncreate ();      LOG.D (TAG, "onCreate () executed"); } @Override public int onstartcommand (Intent Intent, int flags, int startid) {log.d (TAG, "onstartcom          Mand () executed ");      Return Super.onstartcommand (Intent, flags, Startid);          } @Override public void OnDestroy () {Super.ondestroy ();      LOG.D (TAG, "OnDestroy () executed");      } @Override Public IBinder onbind (Intent Intent) {return mbinder; } class Mybinder extends Binder {public void Startdownload () {log.d ("TAG", "startdownload              () executed "); Perform a specific download task}}} 

Here we have added a Mybinder class that inherits from the Binder class, and then adds a Startdownload () method to the Mybinder to perform the download task in the background, but this is not really going to download something, just a test, So the Startdownload () method just prints a single line of logs.

Then modify the code in the Activity_main.xml to add a button to bind the service and unbind the service in the layout file:

<linearlayout xmlns:android= "http://schemas.android.com/apk/res/android" android:layout_width= "Match_parent" android:layout_height= "match_parent" android:orientation= "vertical" > <button android:id= "@+id/ Start_service "android:layout_width=" match_parent "android:layout_height=" Wrap_content "Android : text= "Start Service"/> <button android:id= "@+id/stop_service" android:layout_width= "match          _parent "android:layout_height=" wrap_content "android:text=" Stop Service "/> <button Android:id= "@+id/bind_service" android:layout_width= "match_parent" android:layout_height= "Wrap_conten T "android:text=" Bind Service "/> <button android:id=" @+id/unbind_service "an          Droid:layout_width= "Match_parent" android:layout_height= "wrap_content" android:text= "Unbind Service" /> </Linearlayout>  

The

Then modifies the code in mainactivity to associate mainactivity with MyService, as shown in the following code:

public class Mainactivity extends Activity implements Onclicklistener {private Button startservice;        Private Button StopService;        Private Button Bindservice;        Private Button Unbindservice;        Private Myservice.mybinder Mybinder; Private Serviceconnection connection = new Serviceconnection () {@Override public void Onservicediscon nected (componentname name) {} @Override public void onserviceconnected (componentname name, I              Binder service) {Mybinder = (myservice.mybinder) service;          Mybinder.startdownload ();        }      };          @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); Bindservice = (Button) Findviewbyid (r.id.bind_servICE);          Unbindservice = (Button) Findviewbyid (R.id.unbind_service);          Startservice.setonclicklistener (this);          Stopservice.setonclicklistener (this);          Bindservice.setonclicklistener (this);      Unbindservice.setonclicklistener (this);              } @Override public void OnClick (View v) {switch (V.getid ()) {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              Case R.id.bind_service:intent bindintent = new Intent (this, myservice.class);              Bindservice (bindintent, Connection, bind_auto_create);          Break              Case R.id.unbind_service:unbindservice (connection);          Break  Default:break;        }      }    }   

As you can see, here we first create an anonymous class of Serviceconnection, which overrides the Onserviceconnected () method and the Onservicedisconnected () method, These two methods are called when the activity is associated with the service and disassociate. In the Onserviceconnected () method, we also get an example of mybinder by downward transformation, and with this example, the relationship between activity and service becomes very close. Now we can invoke any public method in the activity according to the specific scenario, that is, the function that the activity directs the service to do what service Mybinder.

Of course, the activity and service are not actually connected now, this function is done in the Click event of the Bind service button. As you can see, we are still building a intent object and then calling the Bindservice () method to bind the activity to the service. The Bindservice () method receives three parameters, the first parameter is the intent object that was just built, the second argument is an instance of the Serviceconnection created earlier, and the third parameter is a flag bit, which is passed in Bind_auto_ Create means that the service is created automatically after the activity and service are established, which causes the OnCreate () method in MyService to be executed, but the Onstartcommand () method does not execute.

And then how do we want to remove the connection between the activity and the service? Call the Unbindservice () method, which is also the logic implemented in the Click event of the Unbind Service button.

Now let's run the program again, click the Bind service button in Mainactivity, and print the log in Logcat as shown:

It is also important to note that any service is common throughout the application, meaning that MyService can be associated not only with mainactivity, but also with any activity. And they can get to the same Mybinder instance when they build the association.

How to destroy a service

In this part of the basic usage of the service, we describe the simplest case of destroying the service, click the Start Service button to start the service, and then click the Stop Service button to stop the service so that the MyService is destroyed. You can see the print log as follows:

So what if we're clicking on the Bind service button? Since the flag bit specified when binding the service is bind_auto_create, the service will be created when the Bind service button is clicked, how should the service be destroyed? In fact, it is also very simple, click on the Unbind Service button, the activity and service related to the release.

Click the Bind Service button first, then click the Unbind Service button, and the print log looks like this:

Both of these methods of destruction are well understood. So what if we clicked the Start Service button and clicked the Bind service button? This time you will find that no matter whether you click the Stop service button alone or the Unbind service button, the service will not be destroyed, and it is necessary to click on all two buttons to be destroyed. That is, 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 when it is not associated with any activity and the stop state is processed.

To confirm, we add a row of print logs to the Click event of the Stop service and Unbind Service button:

public void OnClick (View v) {      switch (V.getid ()) {      r.id.start_service:          Intent startintent = new Intent (t his, myservice.class);          StartService (startintent);          break;      Case R.id.stop_service:          log.d ("MyService", "Click Stop Service Button");          Intent stopintent = new Intent (this, myservice.class);          StopService (stopintent);          break;      Case R.id.bind_service:          Intent bindintent = new Intent (this, myservice.class);          Bindservice (bindintent, Connection, bind_auto_create);          break;      Case R.id.unbind_service:          log.d ("MyService", "Click Unbind Service Button");          Unbindservice (connection);          break;      Default: Break          ;      }  

Then run the program again, click the Start Service button, then click the Bind Service button, and the service starts up and associates with the activity. Then click on the Stop Service button and the service will not be destroyed, then click on the Unbind Service button, the service will be destroyed, the print log is as follows:

We should always remember to clean up those unused resources in the OnDestroy () method of the service, to prevent some objects that are no longer in use after the service is destroyed and still occupy the memory.

Relationship of service and thread

Many Android beginners may have such doubts, service and thread in the end what is the relationship? When should I use the service and when should I use thread? The answer may be a bit of a surprise to you, because there is no relationship between service and thread!

There are a lot of people who will connect them, mainly because of the service background concept. Thread as we all know, is used to open a sub-thread, here to perform some time-consuming operation will not block the main thread running. When we first understand the service, we always feel that it is used to deal with some background tasks, and some more time-consuming operations can be put here to run, which makes people confused. But if I tell you that the service is actually running on the mainline thread, do you still think it has anything to do with thread? Let's take a look at this cruel fact.

Add a line to the Mainactivity's OnCreate () method to print the current thread ID statement:

Then add a line to the MyService's OnCreate () method to print the current thread ID statement:

Now run the program again and click on the Start Service button to see the following print log:

As you can see, their thread IDs are exactly the same, which confirms that the service is actually running on the mainline thread, which means that if you write very time-consuming code in the service, the program is bound to appear anr.

You may exclaim, this is not the pit father!? What's the use of the service? In fact, we do not have to link the background and sub-threads together on the line, this is two completely different concepts. The background of Android is that it runs 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 in progress. For example, some applications, which always require a heartbeat connection to the server, can be implemented using the service. You may also ask, is it not just verified that the service is running on the mainline thread? Is there a heartbeat connection going on here that doesn't block the main thread running? Of course, but we can create a sub-thread in the service and then deal with the time-consuming logic here.

Well, since you also create a sub-thread in the service, why not create it directly in the activity? This is because the activity is difficult to control the thread, and when the activity is destroyed, there is no other way to regain the instance of the previously created child thread. and a child thread created in one activity, another activity cannot manipulate it. But the service is different, all the activity can be associated with the service, and then it is easy to manipulate the method, even if the activity is destroyed, and then just re-associated with the service, It is also possible to obtain an instance of binder in the original service. Therefore, using the service to handle background tasks, activity can safely finish without worrying about situations where background tasks cannot be controlled.

A more standard service can be written as:

@Override public  int Onstartcommand (Intent Intent, int flags, int startid) {      new Thread (new Runnable () {          @Ove Rride public          Void Run () {              //Start background task          }      }). Start ();      Return Super.onstartcommand (Intent, flags, Startid);  }    Class Mybinder extends Binder {public        void Startdownload () {          new Thread (new Runnable () {              @Override              public void Run () {                  //Perform specific download task              }          }). Start ();}    }  
Create a foreground service

Service is running in the background almost all the time, it has been doing a hard work silently. However, the service's system priority is still relatively low, and when the system is out of memory, it is possible to reclaim the service that is running in the background. If you want the service to remain running and not be recycled due to low system memory, consider using a foreground service. The biggest difference between front service and normal service is that it will always have a running icon displayed in the system's status bar, and the drop-down status bar can see more detailed information, very similar to the effect of notifications. Of course, sometimes you may not only use the front service to prevent service from being recycled, some items require a front-end service due to special requirements, such as ink weather, and its service updates the weather data in the background, The current weather information is also displayed in the System status bar, as shown in:

So let's take a look at how we can create a front service, which is actually not complicated, and modifies the code in MyService as follows:

public class MyService extends Service {public static final String TAG = "MyS        Ervice ";        Private Mybinder Mbinder = new Mybinder ();          @Override public void OnCreate () {super.oncreate (); Notification Notification = new Notification (R.drawable.ic_launcher, "Notify Arrival", System.currenttimemillis ())          ;          Intent notificationintent = new Intent (this, mainactivity.class);          Pendingintent pendingintent = pendingintent.getactivity (this, 0, notificationintent, 0);          Notification.setlatesteventinfo (This, "which is the title of the notice", "This is the content of the notice", pendingintent);          Startforeground (1, notification);      LOG.D (TAG, "onCreate () executed");  }        .........    } 

This only modifies the code for the OnCreate () method in MyService. As you can see, we first created a notification object and then called its Setlatesteventinfo () method to initialize the layout and data for the notification, and set the click Notification here to open the mainactivity. You can then call the Startforeground () method to make MyService a foreground service and display the picture of the notification.

Now rerun the program and click on the start service or BIND service button, MyService will start the previous service mode, and in the system status bar will pop up a banner icon, drop down status bar can see the details of the notification, as shown in.

Android Service fully resolves everything you need to know about the service (on)

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.