Introduce IntentService

IntentService is a special type of Service that inherits from Service and is an abstract class, so you must subclass it to use IntentService. It can be used to perform time-consuming tasks in the background. When the task is completed, it will automatically stop. When the resources are insufficient, the system will clean up some resources that are considered useless. So it’s good for high-priority background tasks. Implementatively, IntentService encapsulates Handlerhread and Handler.

HandlerThread descends from Thread, which is a Thread that can use a Handler. Looper.prepare() creates a message queue in the run() method and starts the message loop in the looper.loop () method. The looper.loop () method overwrites the run method of Thread. HandlerThread is told to perform a specific task through Handler messages (Looper loops).

@Override
public void run() {
    mTid = Process.myTid();
    Looper.prepare();
    synchronized (this) {
        mLooper = Looper.myLooper();
        notifyAll();
    }
    Process.setThreadPriority(mPriority);
    onLooperPrepared();
    Looper.loop();
    mTid = -1;
}
Copy the code

If it is clear that a HandlerThread is not needed, use the quit or quitSafely method to terminate the thread

public boolean quit() {
    Looper looper = getLooper();
    if(looper ! = null) { looper.quit();return true;
    }
    return false;
}

public boolean quitSafely() {
    Looper looper = getLooper();
    if(looper ! = null) { looper.quitSafely();return true;
    }
    return false;
}
Copy the code

The differences between the two methods are:

Quit () It may be unsafe to use this method because some messages may not be delivered until the Looper queue terminates.

QuitSafely () It is probably safe to use this method because the method terminates once the message has been delivered and all remaining messages in the queue have been processed. However, delayed messages will not be delivered for future expiration periods until the loop terminates.

IntentService execution sequence is analyzed from source code

Initialize HandlerThread and ServiceHandler in onCreate() to send messages after onStart is called.

@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);
}
Copy the code

The onStartCommand() method is called once each time the service is started, and it calls onStart()

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

Send the message in onStart()

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

Background tasks are executed sequentially because Looper in Handler processes messages sequentially.

End the service after the task is completed:

private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { onHandleIntent((Intent)msg.obj); / / use stopSelf (MSG. Arg1); Instead of using stopSelf(); // Because stopSelf() immediately stops the service, // while stopSelf(msg.arg1); StopSelf (msg.arg1); stopSelf(msg.arg1); }}Copy the code

Use IntentService

Create an instance inherited from IntentService

public class TestIntentService extends IntentService {
    private static final String TAG = "TestIntentService";

    public TestIntentService() {
        super(TAG);
        Log.e(TAG, "TestIntentService: " );
    }

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

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        String taskAction = intent.getStringExtra("task_action");
        SystemClock.sleep(3000);
        Log.e(TAG, "onHandleIntent: "+taskAction);
    }

    @Override
    public void onDestroy() {
        Log.e(TAG, "onDestroy: service destory"); super.onDestroy(); }}Copy the code

Register the service in AndroidMainfest.xml

<service android:name=".thread.TestIntentService"/>
Copy the code

Open the service

Intent intent = new Intent(CallBackTestActivity.this, TestIntentService.class);
intent.putExtra("task_action"."com.dx.action.TASK1"); // Start the first service startService(intent); intent.putExtra("task_action"."com.dx.action.TASK2"); // Start the second service startService(intent); intent.putExtra("task_action"."com.dx.action.TASK3"); // Start the third service startService(intent);Copy the code

The output is:



The timing in the screenshot and the output order confirm the above statement! Ok, done

Original author: dragon clothing, the original link: https://www.jianshu.com/p/92c8a4451bb0



Welcome to follow my wechat public account “Code farming breakthrough”, share Python, Java, big data, machine learning, artificial intelligence and other technologies, pay attention to code farming technology improvement, career breakthrough, thinking transition, 200,000 + code farming growth charge first stop, accompany you have a dream to grow together.