IntentService 是一种特殊的 Service,它继承了 Service 并且它是一个抽象类,因此必须创建它的子类才能使用 IntentService。IntentService 可用于执行后台耗时的任务,当任务执行结束后它会自动停止,同时由于 IntentService 是服务的原因,这导致它的优先级比单纯的线程要高很多,所以 IntentService 比较适合执行一些高优先级的后台任务,因为它优先级高不容易被系统杀死。
一、源码剖析
1. IntentService 是 Service 的子类,所以 IntentService 也是一个服务
public abstract class IntentService extends Service {
······
}
2. IntentService 内部会创建 HandlerThread 和 Handler 实例,并将 HandlerThread 内的 Looper 作为 Handler 的 Looper,服务销毁时退出 Looper
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public void onDestroy() {
mServiceLooper.quit();
}
3. 外部发送的事件会被依次传递到 Handler 中
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
4. 在 Handler 内会调用 onHandleIntent 方法
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);
}
}
当 onHandleIntent 方法执行结束后,IntentService 会通过 stopSelf(int startId) 方法来尝试停止服务。这里之所以采用 stopSelf(int startId) 而不是 stopSelf() 来停止服务,那是因为 stopSelf() 会立刻停止服务,而这个时候可能还有其他消息未处理,stopSelf(int startId) 则会等待所有的消息都处理完毕后才终止服务。一般来说,stopSelf(int startId) 在尝试停止服务之前会判断最近启动服务的次数是否和 startId 相等,如果相等就立刻停止服务,不相等则不停止服务,这个策略可以从 AMS 的 stopServiceToken 方法的实现中找到依据。
二、使用案例
1. 继承 IntentService
public class LocalIntentService extends IntentService {
private static final String TAG = "LocalIntentService";
public LocalIntentService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
String action = intent.getStringExtra("task_action");
Log.d(TAG, "handle task: " + action);
SystemClock.sleep(2000);
}
@Override
public void onDestroy() {
Log.d(TAG, "service destroyed");
super.onDestroy();
}
}
2. 调用
Intent service = new Intent(this, LocalIntentService.class);
service.putExtra("task_action", "TASK1");
startService(service);
service.putExtra("task_action","TASK2");
startService(service);
Log 日志:
2020-12-08 13:18:43.606 D/LocalIntentService: handle task: TASK1
2020-12-08 13:18:45.606 D/LocalIntentService: handle task: TASK2
2020-12-08 13:18:47.608 D/LocalIntentService: service destroyed
网友评论