The use of Intentservice in Android and its source code parsing

Source: Internet
Author: User
Tags terminates

Why do we need Intentservice?

Intentservice in Android is inherited from the service class, before we talk about Intentservice, let's think about the features of the service: the service callback method (OnCreate, Onstartcommand , Onbind, OnDestroy) are all running in the main thread. When we start the service through StartService, we need to write the code in the service's Onstartcommand method, but Onstartcommand is running in the main thread, If we need to complete some time-consuming operations, such as network requests or IO, this will block the main thread UI from being unresponsive, resulting in a ANR behavior. To solve this problem, the best way to do this is to create a new thread in Onstartcommand and put the time-consuming code in the new thread. You can refer to the previous article, "Android through the StartService implementation of bulk Download sample", this article in Onstartcommand opened a new thread as a worker to perform network requests, so this does not block the main thread. From this perspective, creating a service with worker threads is a common requirement (because the worker thread does not block the main thread), so Android has developed a class--–intentservice to simplify the development of service,android with worker threads.

Features of Intentservice

Intentservice has the following characteristics:
1. Intentservice comes with a worker thread and can consider using Intentservice when our service needs to do some work that might block the main thread.
2. we need to put the actual work to be done into Intentservice's onhandleintent back to the method, when we started intentservice through StartService (intent), Eventually the Android framework will callback its Onhandleintent method and pass the intent into the method so that we can do the actual work according to intent, And the onhandleintent runs in a worker thread held by Intentservice, not the main thread.
3. When we start intentservice multiple times through startservice, this results in multiple jobs, because Intentservice only holds one worker thread, so each onhandleintent can only handle one job. What happens when more than one job,intentservice is handled? Processing mode is One-by-one, that is, one by the order of processing, the first intent1 into onhandleintent, let it complete job1, and then intent2 into onhandleintent, let it complete job2 ... This until all job completion, so we Intentservice can not execute multiple jobs in parallel, can only one one in order to complete, when all the job completed Intentservice destroyed, will execute OnDestroy callback method .

How do I use Intentservice?

In the article "Android uses StartService to implement bulk download samples," We showed how to download articles in bulk by service, and now in this article we're going to show you how to download articles in bulk, just to do it with Intentservice.

The system interface is as follows:

The interface is very simple, just a button "bulk download article", through the activity on the button to start Downloadservice.

Downloadservice is a service for downloading blog posts on CSDN, with the following code:

 PackageCom.ispring.startservicedemo;ImportAndroid.app.IntentService;ImportAndroid.content.Intent;ImportAndroid.util.Log;ImportJava.io.IOException;ImportJava.io.InputStream;ImportJava.net.HttpURLConnection;ImportJava.net.MalformedURLException;ImportJava.net.URL; Public  class downloadintentservice extends intentservice {     Public Downloadintentservice(){Super("Download"); LOG.I ("Demolog","Downloadintentservice Constructor, Thread:"+ Thread.CurrentThread (). GetName ()); }@Override     Public void onCreate() {Super. OnCreate (); LOG.I ("Demolog","Downloadintentservice-onCreate, Thread:"+ Thread.CurrentThread (). GetName ()); }@Override     Public int Onstartcommand(Intent Intent,intFlagsintStartid) {LOG.I ("Demolog","Downloadintentservice-Onstartcommand, Thread:"+ Thread.CurrentThread (). GetName () +", Startid:"+ Startid);return Super. Onstartcommand (Intent, flags, Startid); }@Override    protected void onhandleintent(Intent Intent) {HttpURLConnection conn =NULL; InputStream is =NULL; String Blogurl = Intent.getstringextra ("url"); String blogname = Intent.getstringextra ("Name");Try{//Download the specified fileURL url =NewURL (Blogurl); conn = (httpurlconnection) url.openconnection ();if(Conn! =NULL){//We get the input stream for the downloaded article here, which can be written as a file to the memory card or                //Read it out text to display in appis = Conn.getinputstream (); }        }Catch(Malformedurlexception e)        {E.printstacktrace (); }Catch(IOException e)        {E.printstacktrace (); }finally{if(Conn! =NULL) {conn.disconnect (); }} log.i ("Demolog","Downloadintentservice-onhandleintent, Thread:"+ Thread.CurrentThread (). GetName () +","+ Blogname +"Download Complete"); }@Override     Public void OnDestroy() {Super. OnDestroy (); LOG.I ("Demolog","Downloadintentservice-OnDestroy, Thread:"+ Thread.CurrentThread (). GetName ()); }}

The code for Downloadactivity is as follows:

 PackageCom.ispring.startservicedemo;Importandroid.app.Activity;ImportAndroid.content.Intent;ImportAndroid.os.Bundle;ImportAndroid.view.View;ImportAndroid.widget.Button;ImportJava.util.ArrayList;ImportJava.util.HashMap;ImportJava.util.Iterator;ImportJava.util.List;ImportJava.util.Map; Public  class downloadactivity extends Activity implements Button . Onclicklistener {    @Override    protected void onCreate(Bundle savedinstancestate) {Super. OnCreate (Savedinstancestate);    Setcontentview (R.layout.activity_download); }@Override     Public void OnClick(View v) {List<string> List =NewArraylist<> (); List.add ("Use of handler in Android; http://blog.csdn.net/iispring/article/details/47115879"); List.add ("deep source parsing handler,message,messagequeue,looper;http://blog.csdn.net/iispring/article/details/47180325 in Android "); List.add ("Update the View method rollup in the main thread UI in new Android threads; http://blog.csdn.net/iispring/article/details/47300819"); List.add ("Use and principle analysis of handlerthread in Android; http://blog.csdn.net/iispring/article/details/47320407"); List.add ("Quit method and quitsafely method of Looper in Android; http://blog.csdn.net/iispring/article/details/47622705"); Iterator Iterator = List.iterator (); while(Iterator.hasnext ())            {String str = (string) iterator.next (); String[] Splits = Str.split (";"); String name = splits[0]; String URL = splits[1]; Intent Intent =NewIntent ( This, Downloadintentservice.class); Intent.putextra ("Name", name); Intent.putextra ("url", URL);//Start IntentserviceStartService (Intent); }    }}

When we click the button "bulk Download article", we will call the activity's StartService method several times, in which we store the article name name and the address URL of the article in its parameter intent, because we have called the StartService method several times, So the article will be downloaded in bulk.

When you click on the button, the console run results are as follows:

Through the above output we can find that the Downloadintentservice OnCreate, Onstartcommand, OnDestroy callback methods are running in the main thread, While Onhandleintent is running in worker thread Intentservice[download], this validates the first and second features of the intentservice we mentioned above.

From the above output we will also find that after we have called five times startservice (intent), Onstartcommand was called five times, followed by Onhandleintent five times, This completes the job in turn, when the last job is completed, that is, after the last onhandleintent call is completed, the entire intentservice is completed, the OnDestroy callback method is executed, Intentservice destroyed.

Intentservice working principle and source Code analysis

In the above we have introduced the characteristics of intentservice and how to use, then you may wonder how Android will dispatch these intent to the onhandleintent to complete the work, in fact, Intentservice works very simple, Convert the intent to a message and put it in the messages queue, and then let handler take the message out of it to process it.

The source code of Intentservice is as follows:

 PackageAndroid.app;ImportAndroid.content.Intent;ImportAndroid.os.Handler;ImportAndroid.os.HandlerThread;ImportAndroid.os.IBinder;ImportAndroid.os.Looper;ImportAndroid.os.Message; Public Abstract  class intentservice extends Service {    Private volatileLooper Mservicelooper;Private volatileServicehandler Mservicehandler;PrivateString Mname;Private BooleanMredelivery;Private Final  class servicehandler extends Handler {         Public Servicehandler(Looper Looper) {Super(Looper); }@Override         Public void Handlemessage(Message msg) {//Call onhandleintent in the worker thread to ensure that the onhandleintent does not block the main threadOnhandleintent ((Intent) msg.obj);//After executing onhandleintent, we need to call Stopself (Startid) to declare that a job has completed            //When all jobs are completed, Android will callback the OnDestroy method and destroy the IntentserviceStopself (MSG.ARG1); }    } Public Intentservice(String name) {//Name here will be used as the thread name        Super();    Mname = name; } Public void Setintentredelivery(BooleanEnabled) {mredelivery = enabled; }@Override     Public void onCreate() {Super. OnCreate ();//Create Handlerthread, use Mname as the thread name, Handlerthread is intentservice worker threadHandlerthread thread =NewHandlerthread ("intentservice["+ Mname +"]");        Thread.Start (); Mservicelooper = Thread.getlooper ();//Handlerthread The created Looper object is passed to Servicehandler,        //So the handler we created is bound together with Handlerthread through Message QueuingMservicehandler =NewServicehandler (Mservicelooper); }@Override     Public void OnStart(Intent Intent,intStartid) {//Create a Message object in this method and use intent as the obj parameter of the message,        //So the message is associated with intentMessage msg = Mservicehandler.obtainmessage ();        MSG.ARG1 = Startid; Msg.obj = Intent;//Send a message with the intent information associated to handlerMservicehandler.sendmessage (msg); }@Override     Public int Onstartcommand(Intent Intent,intFlagsintStartid) {//intentservice overrides the Onstartcommand callback method: Calls the OnStart callback method internally        //So when we inherit intentservice, we should not overwrite the method, even if we override this method, we should call Super.onstartcommand ()OnStart (Intent, Startid);returnMredelivery?    Start_redeliver_intent:start_not_sticky; }@Override     Public void OnDestroy() {//The Quit method of handler is called in the OnDestroy method, which terminates the message loopMservicelooper.quit (); }@Override     PublicIBinderOnbind(Intent Intent) {return NULL; }protected Abstract void onhandleintent(Intent Intent);}

I've added a lot of comments to the code above, and I'm sure you can understand how Intentservice works by looking directly at the code.

Intentservice inherits from the service class, and Intentservice overrides the OnCreate, Onstartcommand, OnStart, OnDestroy callback methods, And Intentservice also added a Onhandleintent callback method. Here we explain in turn the role of these methods in Intentservice.

onCreate: In the OnCreate callback method, use Mname as the thread name to create a worker thread that Handlerthread,handlerthread is intentservice. Handlerthread after the Start method is executed, it is itself associated with Message Queuing and looper, and Message Queuing begins to loop.

Onstartcommand: Intentservice overrides the Onstartcommand callback method: Calls the OnStart callback method internally.

OnStart: Creates a Message object in the OnStart method and takes intent as the obj parameter of the message, so that the message is associated with the intent. The message associated with the intent message is then sent to handler through the handler SendMessage method.

onhandleintent: When in the OnStart method, the message is placed in the messages queue associated with handler by the SendMessage method, The Looper object that is associated with handler takes a message from the queue of messages and then passes it into the Handlemessage method of handler. In the Handlemessage method, the original intent object is first obtained through obj of the message, which is then passed as a parameter to the Onhandleintent method for execution. The Handlemessage method is run in Handlerthread, so Onhandleintent is also running in the worker thread. After Onhandleintent is executed, we need to call Stopself (Startid) to declare that a job is complete. When all jobs are completed, Android will callback the OnDestroy method and destroy the Intentservice.

OnDestroy: When all jobs are completed, the service destroys and executes its OnDestroy callback method. In this method, the handler quit method is called, and the method terminates the message loop.

Summarize

Intentservice can do work in the worker thread without blocking the main thread, but Intentservice cannot handle multiple jobs in parallel, only sequentially, one after the other, when all the job is done, The OnDestroy method is automatically executed without having to call the Stopself () or stopself (Startid) method ourselves. Intentservice is not a mystery, but Android's encapsulation of a common development approach allows developers to reduce their development effort. Intentservice is an assistant class, and if Android doesn't provide that class it's nothing, we can write a similar one ourselves. Intentservice Service, similar to the handlerthread of handler.

I hope this article is helpful to you to understand Intentservice.

Related reading:
StartService usage and service life cycle in Android
The use and principle analysis of Handlerthread in Android

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

The use of Intentservice in Android and its source code parsing

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.