IntentService源码分析

简介

由于组件Service中不能进行耗时操作(因为Service执行任务是在主线程中执行),所以我们有以下两个方法来解决。

1.可以在Service中开启一个子线程,但是如果Service被杀掉,其开启的子线程也会被销毁。

2.用IntentService来处理:

1.IntentService 是Service的子类,里面自动开启一个子线程来进行耗时操作,当任务结束后,会自动停止,不用调取stopService()。

2.我们继承使用IntentService 时直接使用onHandleIntent()即可,不用重写onBind()和onStartCommond()(这些方法IntentService自动提供了)。

IntentService有以下特点:

  • 默认在子线程中执行回传到onStartCommond()的Intent中。
  • 在重写onHandleIntent()里处理按时间排序的Intent的队列,不必担心多线程带来的问题。
  • 所有请求处理完会自动停止service。
  • 默认实现onBind()方法并返回null。
  • 默认实现了onStratCommond()方法,并将回传的Intent以序列的形式发给onHandleIntent(),你只需重写该方法并处理Intent即可。

onHandleIntent(Intent intent):此方法专门开辟了一个子线程来进行耗时操作的处理,并以队列的形式进行调用,进行排队操作。

如果需要重写其他生命周期方法,需要调用各自的父类方法,保证子线程能够正常启动比如:

 @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG,"onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

需要返回其父类的方法。

源码分析

 @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();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

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

mServiceLooper通过handlerThread.getLooper()获取到,并传入到mServiceHandler中,由于HandlerThread属于异步线程,所以mServiceHandler也变成了一个异步的执行的线程。HandlerThread+Handler构建成了一个带有消息循环机制的异步任务处理机制。因此开发者就可以将异步任务封装成消息的形式发送到工作线程中去执行了。

@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) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

该方法中通过mServiceHandler获得一个消息对象msg,然后将startId作为该消息的消息码,将异步任务请求intent作为消息内容封装成一个消息msg发送到mServiceHandler消息执行者中去处理。这也解释了通常我们在onStartCommand()中去执行一些具体的操作,在onCreate()进行一些初始化操作。

我们再看mServiceHandler的内部代码也就是ServiceHander

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是IntentService的内部类,在重写消息处理方法handlerMessage里面调用了onHandlerIntent抽象方法去处理异步任务intent的请求,在handlerMessage中我们执行了IntentService里面的耗时操作方法onHandleIntent(),由于是在一个子线程中执行的,也就解释了为何可以在onHandleIntent()方法里进行耗时操作的原因,因为他本身就在一个子线程中执行。

执行完OnHandleIntent()方法之后调用stopSelf来结束Service。

stopSelf(): 会立马结束服务

stopSelf(int startId): 等待所有消息都处理完后才终止服务

IntentService本身就是一个队列形式处理异步操作的类,所以使用stopSelf(int startId)是为了让队列中的所有耗时操作全都执行结束之后再结束整个Service。

整理一下IntentService整体的执行顺序:

在onCreate的时候会创建一个HandlerThread对象,并启动线程。紧接着创建ServiceHandler对象,ServiceHandler继承自Handler,用来处理消息。ServiceHandler将获取HandlerThread的Looper就可以开始正常工作了。

每启动一次onStart方法,就会把数消息和数据发给mServiceHandler,相当于发送了一次Message消息给HandlerThread的消息队列。mServiceHandler会把数据传给onHandleIntent方法,onHandleIntent是个抽象方法,需要在IntentService实现,所以每次onStart方法之后都会调用我们自己写的onHandleIntent方法去处理。处理完毕使用stopSelf通知HandlerThread已经处理完毕,HandlerThread继续观察消息队列,如果还有未执行玩的message则继续执行,否则结束。

你可能感兴趣的:(安卓)