我们带着问题来看源码!
一. IntentService如何单独开启一个新的工作线程?
@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();
// 1
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
// 2
mServiceLooper = thread.getLooper();
//3
mServiceHandler = new ServiceHandler(mServiceLooper);
}
1.实例化HandlerThread新建线程并启动,这里注意HandlerThread 继承自Thread,内部封装了Looper;
2. 获得工作线程Looper,并维护自己的工作队列;
3. 实例化ServiceHandler,并绑定获取的Looper,这时属于工作线程。
private final class ServiceHandler extends Handler {
// 1
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
// 2
onHandleIntent((Intent)msg.obj);
// 3
stopSelf(msg.arg1);
}
}
1.构造函数;
2.在工作线程中,将message交给onHandleIntent()方法处理;
3.执行完调用stopSelf()结束服务。
@WorkerThread
// 1
protected abstract void onHandleIntent(@Nullable Intent intent);
1.onHandleIntent()抽象方法使用时需重写
二. IntentService如何通过onStartCommand()将Intent传递给服务并依次插入到工作队列中?
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
我们看下onStartCommand方法中的onStart()函数
@Override
public void onStart(@Nullable Intent intent, int startId) {
// 1
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
// 2
msg.obj = intent;
// 3
mServiceHandler.sendMessage(msg);
}
- 获得ServiceHandler消息的引用;
- 把Intent参数包装到message的obj中发送消息,这里的Intent = 启动服务时StartService(Intent)传入的Intent;
- 使用sendMessage()发送消息,即添加到消息队列里。此时的msg内携带了intent和startId。这里就是最终需要调用的核心函数,源码小伙伴自行查看。
来源:CSDN
作者:古道西风_哥哥
链接:https://blog.csdn.net/m0_37293461/article/details/103663103