First, the definition
Intentservice is a package class in Android that inherits the service from one of the four components.
Second, the role
Processing asynchronous requests, implementing multithreading
Third, the work flow
Note: If you start intentservice multiple times, each time-consuming operation is executed sequentially in the Intentservice Onhandleintent callback method in the queue, completing the automatic end.
Iv. Steps of implementation
- Step 1: Define Intentservice subclasses: Incoming thread name, replication Onhandleintent () method
- Step 2: Register the service in Manifest.xml
- Step 3: Turn on service services in activity
V. Specific examples
- Step 1: Define Intentservice subclasses: Incoming thread name, replication Onhandleintent () method
PackageCom.example.carson_ho.demoforintentservice;ImportAndroid.app.IntentService;ImportAndroid.content.Intent;ImportAndroid.util.Log;/*** Created by Carson_ho on 16/9/28. */PublicClassMyintentserviceExtendsIntentservice {/* Constructor*/PublicMyintentservice () {Calling the constructor of the parent classConstructor parameter = Name of the worker threadSuper"Myintentservice"); }/* Replication Onhandleintent () method*/Implementing time-consuming tasks@OverrideProtectedvoidOnhandleintent (IntentIntent) {Different transaction processing according to the different intentString TaskName= Intent. Getextras (). getString ("TaskName");Switch (taskname) {Case"Task1":Log. I ("Myintentservice","Do Task1");BreakCase"Task2":Log. I ("Myintentservice","Do Task2");BreakDefault:Break } }@OverridePublicvoidOnCreate () {Log. I ("Myintentservice","OnCreate");Super. OnCreate (); }/* Replication Onstartcommand () method*/The default implementation adds the requested intent to the work queue@OverridePublicIntOnstartcommand (IntentIntentint flags, int startid) {log.i (" Myintentservice ", "); return super.onstartcommand (intent, flags, startId);} Span class= "Pl-k" > @Override public void ondestroy () { Span class= "Pl-smi" >log.i ( "Myintentservice" Ondestroy "); super.ondestroy ();}
- Step 2: Register the service in Manifest.xml
<Android:name=". Myintentservice" > <intent-filter > <android: name="Cn.scu.finch"/> </intent-filter> </service>
- Step 3: Turn on service services in activity
PackageCom.example.carson_ho.demoforintentservice;ImportAndroid.content.Intent;ImportAndroid.os.Bundle;Importandroid.support.v7.app.AppCompatActivity;PublicClassMainactivityExtendsappcompatactivity {@OverrideProtectedvoidOnCreate (BundleSavedinstancestate) {Super. OnCreate (Savedinstancestate); Setcontentview (R. layout. Activity_main);The same service will only open one worker threadThe intent request is processed sequentially in the Onhandleintent function.Intent I=NewIntent ("Cn.scu.finch");Bundle bundle=NewBundle (); Bundle. putstring ( "Taskname" "Task1"); I.putextras (bundle); StartService (i); intent i2 = new Intent ("); bundle bundle2 = new Bundle (); Bundle2.putstring ( "Taskname", Span class= "pl-s" > "Task2"); I2.putextras (bundle2); StartService (I2); StartService (i); //Multiple Launches}}
Vi. Source Code Analysis
Next, we will solve the following problems through source code analysis:
- Intentservice How to open a new worker thread separately;
- How Intentservice is passed to the service via Onstartcommand () intent is inserted into the work queue sequentially
Question 1:intentservice How to open a new worker thread individually
The OnCreate () method in Intentservice source code@OverridePublicvoid OnCreate () {Super. OnCreate ();Handlerthread inherits from thread and internally encapsulates the LooperCreate a new thread and start by instantiating HandlerthreadSo no additional new threads are required when using IntentserviceHandlerthread thread=NewHandlerthread ("Intentservice["+ Mname+"]"); Thread. Start ();Get the Looper of the worker thread and maintain your own work queue Mservicelooper= Thread. Getlooper ();Bind the above obtained looper with the newly created MservicehandlerThe new handler is part of the worker thread. Mservicehandler=NewServicehandler (mservicelooper);}PrivateFinalClassServicehandlerExtendsHandler {PublicServicehandler (LooperLooper) {Super (Looper); }Intentservice the Handlemessage method to give the received message to onhandleintent () processing//onhandleintent () is an abstract method that needs to be overridden when using @Override public void handlemessage (Message msg) {//Onhandleintent method executes in the worker thread and finishes calling Stopself () end service. Onhandleintent ((intent) msg.obj); //onhandleintent will call Intentservice () to stop automatically after processing is complete. Stopself (Msg.arg1);}} ////onhandleintent () is an abstract method that needs to be overridden when used @WorkerThread Span class= "Pl-k" >protected abstract void onhandleintent ( intent Intent);
/span>
Question 2:intentservice How to pass Onstartcommand () to the service intent is inserted into the work queue sequentially
Publicint Onstartcommand (Intent Intent,int flags,int Startid) {OnStart (intent, Startid);Return Mredelivery?Start_redeliver_intentstart_not_sticky;} public void OnStart (intent Intent, int startid) {message msg = mservicehandler.arg1 = startid; //wraps the intent parameter into obj of message, then sends a message, which is added to the message queue // The Intent here is Intent in StartService (Intent) When the service is started. Msg.obj = intent; Mservicehandler.sendmessage (msg);} //purge messages in message queue @Override public void OnDestroy () {mservicelooper.quit ();}
/span>
So we onhandleintent () by means of the replication method, and then we can do different threading on the inside according to the intent different.
Note The work task queue is executed sequentially.
If a task is executing in Intentservice, and you send a new task request again, the new task waits until the previous task is completed before execution begins.
Reason:
- Because the OnCreate () method is only called once, only one worker thread is created;
- When StartService (Intent) is called multiple times (Onstartcommand will also be called multiple times) it does not actually create a new worker thread, just waits for the message to be queued for execution, so multiple starts intentservice sequentially executes the event
- If the service is stopped, messages in the message queue are purged, and subsequent events are not executed.
Vii. use of the scene
Thread tasks need to be executed sequentially, in the background
The most common scenario: offline download
Since all tasks are done in the same thread looper, it does not conform to the scenario where multiple data is requested at the same time.
Comparison between 8.1 Intentservice and service
Service: Dependent on the main thread of the application (not a separate process or thread)
It is not recommended to write time-consuming logic and operations in the service, otherwise it will cause ANR;
Intentservice: Create a worker thread to handle multi-threaded tasks
8.2 Intentservice differs from other threads
Intentservice internal uses the Handlerthread implementation, the function resembles the background thread;
Compared to the background thread,
Intentservice is a backend service
, the advantage is: high priority (not easily killed by the system), so as to ensure the execution of the task
For a background thread, if there are four components in the process that are not active, the thread has a very low priority, is easily killed by the system, and cannot guarantee the execution of the task.
Ix. Articles of Reference
Https://github.com/LRH1993/android_interview/blob/master/android/basis/IntentService.md
Android Interview Collection record 9 Intentservice detailed