IntentService explain (to use the source code from the line and again)

Why IntentService?

We know, Service as one of the four components, they will be running in the main thread, so if we have a time-consuming operation, you should open a new thread.
To this end android provides a dedicated class, is IntentService, its inside contains a handler for processing a background thread.
Use IntentService, first of all inherit it, and then realize onHandleIntent () method.

For example, simulation demo upload and download files:
My IntentService:

package example.ylh.com.service_demo;

import android.app.IntentService;
import android.content.Intent;
import android.util.Log;

/**
 * Created by yangLiHai on 2017/8/30.
 */

public class TestIntentService extends IntentService {

    private String TAG = TestIntentService.class.getSimpleName();
    public static final String ACTION_UPLOAD_FILE = "action_upload_file";
    public static final String ACTION_DOWNLOAD_FILE = "action_download_file";

    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     *
     *  Used to name the worker thread, important only for debugging.
     */
    public TestIntentService() {
        super("test intent service");
        Log.e(TAG,"construction");
    }

    @Override
    public void onCreate() {
        Log.e(TAG,"oncreate");
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        Log.e(TAG,"ondestroy");
        super.onDestroy();
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        String action = intent.getAction();
        if (action.equals(ACTION_DOWNLOAD_FILE)){
            downloadFile();
        }else if (action.equals(ACTION_UPLOAD_FILE)){
            uploadFile();
        }
        try {
            Thread.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void uploadFile(){

        Log.e(TAG,"handleintent upload:"+Thread.currentThread().getId()+"");
    }
    private void downloadFile(){

        Log.e(TAG,"handleintent download:"+Thread.currentThread().getId()+"");
    }
}

activity Code:

package example.ylh.com.service_demo;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;

import example.ylh.com.R;

/**
 * Created by yanglihai on 2017/8/17.
 */

public class ServiceTestActivity extends Activity {

    public static final String TAG = ServiceTestActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.service_test_activity);

        findViewById(R.id.btn4).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startUploadService();
            }
        });
        findViewById(R.id.btn5).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startDownloadService();
            }
        });
    }

    public void startDownloadService(){
        Intent i = new Intent(ServiceTestActivity.this, TestIntentService.class);
        i.setAction(TestIntentService.ACTION_DOWNLOAD_FILE);
        startService(i);
    }
    public void startUploadService(){
        Intent i = new Intent(ServiceTestActivity.this, TestIntentService.class);
        i.setAction(TestIntentService.ACTION_UPLOAD_FILE);
        startService(i);
    }


}

To pass data through Intent, distribute different tasks. Multiple calls can be placed inside the handler queue, any time there is only one intent is being processed, the queue when there is no need to handle the task, it will destroy itself.
Click the button to print two times were as follows:

You can clearly see, upload and download tasks are performed in the sub-thread, when all the tasks complete execution will destroy. So use IntentService we do not consider the life cycle of Service, do not have to create your own child thread open tasks, everything is done to help us, it is still very easy to use.

IntentService source parsing
IntentService inherited from the Service, he is a special service, it's inside the package and the HandlerThread Handler.
This is its onCreate method:


    @Override
    public void onCreate() {
        // TODO: It would be nice to have an option to hold a partial wakelock
        // during processing, and to have a static startService(Context, Intent)
        // method that would launch the service & hand off a wakelock.

        super.onCreate();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

When you first start, onCreate method is called, created a HandlerThread, and then use it to construct a looper mServiceHandler (a handler objects). Such mServiceHandler can handle the task in a child thread. After performing oncreat, will perform onStartCommand method, repeatedly invoked onStartCommand start IntentService method multiple times,
which is the specific code onStartCommand method:

@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
    onStart(intent, startId);
    return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}

You can see inside called onStart method, let us look at onStart method:

@Override
   public void onStart(@Nullable Intent intent, int startId) {
       Message msg = mServiceHandler.obtainMessage();
       msg.arg1 = startId;
       msg.obj = intent;
       mServiceHandler.sendMessage(msg);
   }

In onStart method, each time a message is sent with mServiceHandler, then we take a look at mServiceHandler code:

private final class ServiceHandler extends Handler {
      public ServiceHandler(Looper looper) {
          super(looper);
      }

      @Override
      public void handleMessage(Message msg) {
          onHandleIntent((Intent)msg.obj);
          stopSelf(msg.arg1);
      }
  }

You can clearly see, after each received intent, the intent will be to onHandleIntent method to deal with, that is the way we need to be rewritten, by intent that we can parse out the data passed in the outside world, handled accordingly. After onHandleIntent executed, and executed stopSelf (int startid) method to close itself. But he is not going to close immediately, but wait until after all of the intent to terminate the service to be processed. In general, stopSelf (int startId) before closing the recently launched service will determine the number and startId equality, immediately stop the service if they are equal, if not equal, not to stop.

Under IntentService most cases are very simple and practical, you only need to generate a background task operations without time to start the relationship, if sending multiple Intent to IntentService, these Intent will be executed sequentially, each execution a. If there is concurrent demand, not suitable for use IntentService, or write it yourself Service.

IntentService here has been finished, read my examples look at the source, I believe you have been able to fully understand.
If there is not accurate enough to say please give me a message, thank you.

Published 17 original articles · won praise 12 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_24295537/article/details/77801373