Intentservice source code

Source: Internet
Author: User

What can intentservice do:

If you have a task that is divided into N subtasks, you need to complete them in order. If you need to put it in a service, intentservice will make the best choice.


What is intentservice:

Intentservice is a service (it looks like nonsense, but the first thing I can see is intent .), Therefore, if you customize an intentservice, you must declare it in androidmanifest. xml.

From the above "What can we do", we can probably guess what features intentservice has.

First, it should be clear that if a service is enabled in the activity, the service is in the main thread. Therefore, a worker thread is required in intentservice to complete the intent request. This prediction can be confirmed by the definition of intentservice:

IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
Intentservice is used to process asynchronous requests as required (sent in intent mode ). The client sends a request by calling startservice (intent). The service starts as required and processes each intent (request) with its own working thread (different from the main UI thread ), when all requests are completed, they are automatically disabled.


Intentservice source code parsing:

Good news! The intentservice code contains a worker thread, a loose of the worker thread, and a handler of the worker thread. The worker thread is used to work, And The logoff is used to run the thread. the handler is responsible for transmitting the work content to the thread. The source code of intentservice is concise and thorough, reflecting this mechanism. It is worth looking at this mechanism. The source code is as follows:

Path: Alps \ frameworks \ base \ core \ Java \ Android \ app \ intentservice. Java

public abstract class IntentService extends Service {    private volatile Looper mServiceLooper;    private volatile ServiceHandler mServiceHandler;    private String mName;    private boolean mRedelivery;    private final class ServiceHandler extends Handler {        public ServiceHandler(Looper looper) {            super(looper);        }        @Override        public void handleMessage(Message msg) {
// The Custom intentservice subclass mainly implements the onhandleintent function. Note that after this operation
// Stopself. The input parameter is startid. Onhandleintent (intent) MSG. OBJ); stopself (MSG. arg1) ;}}/*** creates an intentservice. invoked by your subclass's constructor. ** @ Param name used to name the worker thread, important only for debugging. */Public intentservice (string name) {super (); mname = Name;}/*** sets intent redelivery preferences. usually called from the constructor * With your preferred semantics. ** <p> if enabled is true, * {@ link # onstartcommand (intent, Int, INT)} will return * {@ Link Service # start_redeliver_intent }, so if this process dies before * {@ link # onhandleintent (intent)} returns, the process will be restarted * and the intent redelivered. if multiple intents have been sent, only * The most recent one is guaranteed to be redelivered. ** <p> if enabled is false (the default), * {@ link # onstartcommand (intent, Int, INT)} will return * {@ Link Service # start_not_sticky }, and if the process dies, the intent * dies along with it. */Public void setintentredelivery (Boolean enabled) {mredelivery = enabled;} @ override public void oncreate () {// todo: it wocould be nice to have an option to hold a partial wakelock // during processing, and to have a static startservice (context, intent) // method that wocould launch the Service & hand off a wakelock. super. oncreate ();
// Take a good look at the following code, start a working thread, get the Logoff of the thread, and then use this logoff to initialize the handler handle.
// In this way, the task can be directly put into the working thread in the form of mhandler. sendmessage.
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");        thread.start();        mServiceLooper = thread.getLooper();        mServiceHandler = new ServiceHandler(mServiceLooper);    }    @Override    public void onStart(Intent intent, int startId) {
// Obtain a message from the message queue. Generally, a message is initialized in this way, instead of in the new message () format.
// Higher efficiency, more robust code message MSG = mservicehandler. obtainmessage (); MSG. arg1 = startid; // MSG. OBJ = intent; // This is the intent passed in when startservice, mservicehandler. sendmessage (MSG); // pass the message containing the request content intent to the working thread}/*** you shocould not override this method for your intentservice. instead, * override {@ link # onhandleintent}, which the system CILS when the intentservice * es a start request. * @ see android. app. service # onstartcommand */@ override public int onstartcommand (intent, int flags, int startid ){
// Note that onstart is called and the input value. Onstart (intent, startid); Return mredelivery? Start_redeliver_intent: start_not_sticky;} @ override public void ondestroy () {mserviceloading. quit ();}/*** unless you provide binding for your service, you don't need to implement this * method, because the default implementation returns NULL. * @ see android. app. service # onbind */@ override public ibinder onbind (intent) {return NULL;}/*** this method is invoked on the worker thread with a request to process. * Only one intent is processed at a time, but the processing happens on a * worker thread that runs independently from other application logic. * So, if this Code takes a long time, it will hold up other requests to * The same intentservice, but it will not hold up anything else. * When all requests have been handled, the intentservice stops itself, * So you shoshould not call {@ link # stopself }. ** @ Param intent the value passed to {@ link * android. content. context # startservice (intent )}. */protected abstract void onhandleintent (intent );}

Slave thread analysis:

For custom intentservice, you can print thread. currentthread (). getname () in the function to print the current thread. You will find that only onhandleintent execution is in another new thread, and other functions (oncreate/onstart/onstartcommand) are executed in the main thread (main thread name.


Sample Code:

The actual code is as follows:

package com.example.fmdemo;import android.app.IntentService;import android.content.Intent;import android.os.IBinder;import android.util.Log;public class IntentServiceDemo extends IntentService {private static final String TAG = "IntentServiceDemo";public IntentServiceDemo() {super("IntentServiceDemo");}public IntentServiceDemo(String name) {super(name);// TODO Auto-generated constructor stub}@Overrideprotected void onHandleIntent(Intent arg0) {// TODO Auto-generated method stubString action = arg0.getExtras().getString("param");if ("oper1".equals(action)) {Log.i(TAG, "onHandleIntent oper1 threadname = "+ Thread.currentThread().getName());} else if ("oper2".equals(action)) {Log.i(TAG, "onHandleIntent oper2 threadname = "+ Thread.currentThread().getName());}try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubLog.i(TAG, "onBind threadname = " + Thread.currentThread().getName());return super.onBind(intent);}@Overridepublic void onCreate() {// TODO Auto-generated method stubLog.i(TAG, "onCreate threadname = " + Thread.currentThread().getName());super.onCreate();}@Overridepublic void onDestroy() {// TODO Auto-generated method stubLog.i(TAG, "onDestroy threadname = " + Thread.currentThread().getName());super.onDestroy();}@Overridepublic void onStart(Intent intent, int startId) {// TODO Auto-generated method stubLog.i(TAG, "onStart threadname = " + Thread.currentThread().getName());super.onStart(intent, startId);}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// TODO Auto-generated method stubLog.i(TAG, "onStartCommand threadname = "+ Thread.currentThread().getName());return super.onStartCommand(intent, flags, startId);}@Overridepublic void setIntentRedelivery(boolean enabled) {// TODO Auto-generated method stubLog.i(TAG, "setIntentRedelivery threadname = "+ Thread.currentThread().getName());super.setIntentRedelivery(enabled);}}

Add the following code in oncreate of the custom activity:

Intent startServiceIntent = new Intent("com.example.fmdemo.intentservice");Bundle bundle = new Bundle();bundle.putString("param", "oper1");startServiceIntent.putExtras(bundle);startService(startServiceIntent);Intent startServiceIntent2 = new Intent("com.example.fmdemo.intentservice");Bundle bundle2 = new Bundle();bundle2.putString("param", "oper2");startServiceIntent2.putExtras(bundle2);startService(startServiceIntent2);

The running result is as follows:

07-01 06:58:23.557: I/IntentServiceDemo(3732): onCreate threadname = main07-01 06:58:23.571: I/IntentServiceDemo(3732): onStartCommand threadname = main07-01 06:58:23.571: I/IntentServiceDemo(3732): onStart threadname = main07-01 06:58:23.576: I/IntentServiceDemo(3732): onHandleIntent oper1 threadname = IntentService[IntentServiceDemo]07-01 06:58:23.577: I/IntentServiceDemo(3732): onStartCommand threadname = main07-01 06:58:23.577: I/IntentServiceDemo(3732): onStart threadname = main07-01 06:58:25.577: I/IntentServiceDemo(3732): onHandleIntent oper2 threadname = IntentService[IntentServiceDemo]07-01 06:58:27.579: I/IntentServiceDemo(3732): onDestroy threadname = main

We can see that onhandleintent runs in the working thread of different main threads.

Intentservice is easy to use, but the implementation mechanism is interesting. If you are interested, you can enter the code.


References:

1. Principles and usage of intentservice in Android

2. intentservice

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.