IntentService是什么
IntentService是一个服务类,它是Service的一个子类,同时因为它内部封装了HandlerThread,所以又是一个异步任务类。
IntentService有哪些优点
1.IntentService是一个服务,优先级比较高,进行后台任务时,没那么容易被杀死。
2.IntentService内部封装了HandlerThread,不用手动创建进程,使用简单。
3.IntentService的后台任务执行完后自动销毁,不必手动销毁。
IntentService的使用
先新建一个类继承IntentService,然后复写onHandlerIntent(Intent intent),然后在onHandlerIntent写后台执行的任务。这个方法的Intent和你启动Intentservice传入的Intent是同一个东西,所以在方法里,可以根据Intent传入的参数进行分类判断要执行的后台任务。这里给出一个例子:
mTvText.setOnClickListener(v -> {
Intent intent = new Intent(MultiThreadActivity.this, MyIntentService.class);
intent.putExtra("task", "task1");
startService(intent);
Intent intent1 = new Intent(MultiThreadActivity.this, MyIntentService.class);
intent.putExtra("task", "task2");
startService(intent1);
});
public class MyIntentService extends IntentService {
private final static String TAG = MyIntentService.class.getSimpleName();
private int mStartId;
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*/
public MyIntentService() {
super("MyIntentService");
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate: ");
}
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand: ");
mStartId = startId;
return super.onStartCommand(intent, flags, startId);
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
// 在子线程中执行(可以做耗时操作)
String taskTips = intent.getStringExtra("task");
switch (taskTips) {
case "task1":
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
case "task2":
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: ");
}
}
IntentService原理
在了解IntentService原理之前,我们先了解一下HandlerThread。
HandlerThread是一个线程类,它继承了Thread,里面又对Handler进行了封装,所以它是Thread和Handler的结合的一个类。HandlerThread的源码很简单,我们着重看它的run方法:
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
当创建一个HandlerThread线程,并启动线程,线程运行的时候执行它的run方法,run方法中为该线程创建Looper,并轮询消息。
当我们启动IntentService的时候,会调用IntentService的onCreate -> onStartCommand,当任务没有执行完,又启动Service时,它不会重新创建一个服务,而是调用onStartCommand,当任务都执行完后,销毁服务。我们来看看IntentService内部都做了什么。
onCreate方法中,创建一个HandlerThread实例,并启动线程。然后拿到HandlerThread中的Looper来创建Handler。然后在onStart方法中,创建一个消息,handler发送到子线程的消息队列中,在经过Looper的轮询取出,然后调用Handler的handleMessage方法处理消息。由于这个mServicehandler与子线程中Looper绑定,所以handleMessage()方法中仍然是在子线程中。又因为,多次启动服务时,不会重新创建服务,onCreate方法只会调用一次,所以自始至终只在一个线程中执行任务,并且任务执行的顺序是串行的,因为每一个任务都会放入消息队列中轮询执行。回到handleMessage方法中,先执行我们实现的onHandlerIntent方法去处理我们要处理的后台任务,然后在执行stopSelf方法。当这个startId等于最近IntentService启动次数相同的时候,就会销毁这个服务。
stopSelf()方法中,会调用Service的stopSelf(),最终会调用mActivityManager.stopServiceToken(new ComponentName(this,mClassName),mToken, startId)。底层方法中,会根据starid是否等于最近启动服务的次数来判断是否停止服务。
参考《Android开发艺术探索》