IntentService原理

2018-04-08  本文已影响6人  gczxbb

IntentService是一个抽象类,它的本质是Service组件,使用者需要重写它的onHandleIntent方法。

@WorkerThread
protected abstract void onHandleIntent(Intent intent);

从这个抽象方法可以看出,它并不在主线程中工作。Service组件虽然是后台服务,但是,他是在主线程工作的,不可以做耗时操作,而IntentService就是一种可以在非主线程工作的服务。

@Override
public void onCreate() {
    super.onCreate();
    HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
    thread.start();

    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
}

Service启动时,在onCreate方法,创建一个HandlerThread线程,它内部实现了Looper循环,可以接收消息。

public void run() {
    mTid = Process.myTid();
    Looper.prepare();
    synchronized (this) {
        mLooper = Looper.myLooper();
        notifyAll();
    }
    Process.setThreadPriority(mPriority);
    onLooperPrepared();
    Looper.loop();
}

然后,创建一个ServiceHandler,绑定这个Looper。

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);
    }
}

这样,ServiceHandler专注处理HandlerThread线程队列的消息,在handleMessage方法处理消息时,调用实现类IntentService重写的onHandleIntent方法。onStart方法发送消息。

@Override
public void onStart(Intent intent, int startId) {
    Message msg = mServiceHandler.obtainMessage();
    msg.arg1 = startId;
    msg.obj = intent;
    mServiceHandler.sendMessage(msg);
}

具体流程是这样的:主线程启动IntentService服务,先调用第一个生命周期onCreate方法,构建一个线程消息循环和一个Handler触发器,然后,执行onStart方法时,向线程消息队列发送消息,线程处理耗时操作,在IntentService预留抽象方法实现。处理完成,stopSelf根据startId停止Service,并在onDestroy结束掉线程消息循环。

@Override
public void onDestroy() {
    mServiceLooper.quit();
}
IntentService服务架构图。 IntentService服务架构图.jpg

总结

IntentService是框架层提供的可进行耗时操作的服务,原理是基于内部线程循环+Handler模型,与主线程消息循环不同的是,它建立的是非主线程的消息循环。当主线程启动服务,发送消息,线程便开始回调服务预留的耗时方法。主线程仅负责在服务onStart时发送消息的工作。当执行完成后,自动停止服务,关闭消息循环。HandlerThread是系统框架中一个自带启动Looper循环的线程。


任重而道远

上一篇 下一篇

猜你喜欢

热点阅读