IntentService
我们直接分析 IntentService
的源码,如下:
public abstract class IntentService extends Service {
// Looper 对象
private volatile Looper mServiceLooper;
// Handler 对象
private volatile ServiceHandler mServiceHandler;
// 线程名称
private String mName;
private boolean mRedelivery;
// Handler 内部类
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
// 抽象方法,子类覆写来执行具体的业务逻辑
onHandleIntent((Intent)msg.obj);
// 根据 startId 来销毁自身,如果多次启动服务,最后一次才会销毁成功并回调 onDestroy
stopSelf(msg.arg1);
}
}
public IntentService(String name) {
super();
// 设置线程名称
mName = name;
}
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
@Override
public void onCreate() {
super.onCreate();
// 创建 HandlerThread
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
// 启动
thread.start();
mServiceLooper = thread.getLooper();
// 创建 Handler
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
// 把相应信息封装成 Message 对象
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 方法
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onDestroy() {
// 退出循环,即销毁线程,回收资源
mServiceLooper.quit();
}
@Override
@Nullable
public IBinder onBind(Intent intent) {
// 直接返回 Null
return null;
}
// 抽象方法,子类覆写来执行具体的业务逻辑
@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent);
}
实现逻辑分析:
在
onCreate()
方法中使用了一个HandlerThread
来维护线程,传入HandlerThread
内部维护的Looper
来创建ServiceHandler
。在
onStart()
方法中将Intent
和startId
作为参数封装进了Message
,并发送到ServiceHandler
来处理。在
onStartCommand()
方法直接调用第二步的onStart()
方法。在
Handler
的handleMessage()
回调中会调用抽象方法onHandleIntent()
,执行完之后,会调用stopSelf(startId)
方法来销毁自身,每次启动服务时startId
都会不一样,只有当最近的onStart()
的startId
等于stopSelf(startId)
时才会销毁成功并回调onDestroy()
方法。比如说,如果只启动一次服务,第一次启动时,startId
为1
,那么执行stopSelf(startId)
时的startId
也为 1 ,则销毁成功。如果启动了两次服务,假设第二次启动时startId
为2
,当处理第一次的逻辑时执行到stopSelf(startId)
,此时的startId
为上一次的startId
,即为1
,则销毁不成功,继续处理第二次的处理逻辑,处理完才会销毁成功。也就是说,多次启动服务时,会顺序处理每次的请求,全部处理完后,才销毁服务 。在
onDestroy()
中会退出循环,即销毁线程,回收资源。
IntentService 使用示例
自定义 IntentService
类:
public class TestIntentService extends IntentService {
private static final String PARAM = "test";
public TestIntentService() {
super("TestIntentService");
}
public static void startIntentService(Context activity, String param) {
Intent intent = new Intent(activity, TestIntentService.class);
intent.putExtra(PARAM, param);
activity.startService(intent);
}
@Override
protected void onHandleIntent(Intent intent) {
Log.d("TestIntentService", "onHandleIntent 线程名称" + Thread.currentThread().getName());
if (intent.getStringExtra(PARAM).equals("first")) {
try {
Log.d("TestIntentService", "first start");
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
try {
Log.d("TestIntentService", "again start");
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("TestIntentService", "onDestroy 线程名称" + Thread.currentThread().getName());
}
}
启动服务:
if (isReadStart) {
TestIntentService.startIntentService(this, "again");
} else {
TestIntentService.startIntentService(this, "first");
isReadStart = true;
}
打印日志:
D/TestIntentService: onHandleIntent 线程名称 IntentService[TestIntentService]
D/TestIntentService: first start
D/TestIntentService: onHandleIntent 线程名称 IntentService[TestIntentService]
D/TestIntentService: again start
D/TestIntentService: onDestroy 线程名称 main