Reprint please indicate source: a maple leaf column
In the last article we looked at handlerThreads, which are essentially a Thread but internally define their own Looper and MessageQueue. In order to facilitate communication between multiple threads, we will use Handler to implement communication between threads. At this point our manual implementation of a simplified version of multithreading +Handler is what HandlerThrea is all about. For more information about HandlerThread, please refer to IntentService
In this article we will cover IntentService. What is an IntentService? IntentService is a Service that contains a message loop. First, it is a Service, so it has all the features associated with a Service. It also has some properties of its own, which encapsulates a message queue and a HandlerThread. In its concrete abstract method, the onHandleIntent method runs in its message queue thread. Without further discussion, let’s look at its simple usage:
Public class MIntentService extends IntentService{public MIntentService() {super(""); } @Override protected void onHandleIntent(Intent intent) { Log.i("tag", intent.getStringExtra("params") + " " + Thread.currentThread().getId()); }}Copy the code
- Define the service in androidmanifest.xml
Copy the code
/** * Define TextView click event, @override public void onClick(View v) {Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, MIntentService.class); intent.putExtra("params", "ceshi"); startService(intent); }});Copy the code
When the title component is clicked, the service receives the message and prints the intent parameter that was passed to it. The ID of the thread executing the onHandlerIntent method is not the main thread.
Let’s look at the source of the service:
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) { 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; } @Override public void onCreate() { super.onCreate(); HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); } @Override public void onStart(Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); } /** * You should not override this method for your IntentService. Instead, * override {@link #onHandleIntent}, which the system calls when the IntentService * receives a start request. * @see android.app.Service#onStartCommand */ @Override public int onStartCommand(Intent intent, int flags, int startId) { onStart(intent, startId); return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; } @Override public void onDestroy() { mServiceLooper.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 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 should not call {@link #stopSelf}. * * @param intent The value passed to {@link * android.content.Context#startService(Intent)}. */ @WorkerThread protected abstract void onHandleIntent(Intent intent); }Copy the code
How, the code is fairly simple, first of all, by definition we can know the IntentService is a Service, and is an abstract class, so we need to implement the abstract methods in succession IntentService: onHandlerIntent.
Let’s look at its onCreate method:
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}Copy the code
It defines a HandlerIThread (essentially a thread that contains a message queue)
Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler
Then we find that the onStartCommand method is the same as the onStart method.
@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}Copy the code
An intent received at startup is sent to a message queue for processing.
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); }}Copy the code
You can see that the handleMessage method is executing two pieces of logic inside of it. One is calling its onHandlerIntent abstract method, and by analyzing the creation of its onCreate method handler object we know that its handler object is attached to the HandlerThread thread, So its handeMessage method is also executed in the HandlerThread thread, confirming one of the conclusions in our previous example. OnHandlerIntent is executed in a child thread.
The stopSelf method is passed msg.arg1. We know from the onStart method that we passed startId. We know from other articles that since the service can be started N times, it can pass messages N times. Calling stopSelf(startId) when an IntentService has a message in its message queue does not stop itself immediately. It stops itself only when the last message in the message queue has been executed.
IntentServie IntentServie is a Service object that contains a message queue.
Conclusion:
-
IntentService is a service and an abstract class;
-
Inheriting IntentService requires the implementation of its onHandlerIntent abstract method;
-
OnHandlerIntent is executed in a child thread;
-
IntentService holds member variables such as HandlerThread, Looper, and Handler, and maintains its own message queue.
-
Each time an IntentService background task is completed, it tries to stop itself, but only when the last message in the IntentService message queue has been executed.
In addition to the Android source code parsing method of interest can refer to my: Android project construction process android source code parsing (2) – > Asynchronous message mechanism android source code parsing (3) – > asynchronous task AsyncTask Android source code parsing (4) – >HandlerThread
This article is synchronized to Github:Github.com/yipianfengy…Welcome star and Follow