IntentService源码分析

☆樱花仙子☆ 提交于 2019-12-27 07:20:53

我们带着问题来看源码!

一. 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);
}
  1. 获得ServiceHandler消息的引用;
  2. 把Intent参数包装到message的obj中发送消息,这里的Intent = 启动服务时StartService(Intent)传入的Intent;
  3. 使用sendMessage()发送消息,即添加到消息队列里。此时的msg内携带了intent和startId。这里就是最终需要调用的核心函数,源码小伙伴自行查看。
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!