IntentService源码解析

IntentService源码解析 | Tianbin’s Notes

本文主要分析IntentService的内部实现流程,涉及ServiceHandlerThreadHandlerLooperMessageQueue等相关内容。

示例代码

public class JobIntentService extends IntentService {
    public static void start(Context context) {
        Intent intent = new Intent(context, JobIntentService.class);
        intent.setAction("com.tianbin.service.jobintentservice");
        context.startService(intent);
    }
    public JobIntentService() {
        super("JobIntentService");
    }
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        if (intent == null) {
            return;
        }
        Log.e("tag", intent.getAction());
    }
}

源码分析

调用以上示例中的start方法后,Logcat中会输出com.tianbin.service.jobintentservice,也就是在start方法中为Intent设置的action

下面就以start方法为入口进行梳理。

IntentService

IntentService继承自Service,从Service的生命周期可以了解到,调用Context.startService方法会创建Service并调用它的onStartCommand方法。

以下是IntentService.onStartCommand相关源码

@Override
   public void onStart(@Nullable Intent intent, int startId) {
       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(intent, startId);
       return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
   }

onStartCommand方法调用了ServiceonStart方法,而在onStart方法内,则是调用ServiceHandler发送了一个Message

ServiceHandlerIntentService的内部类,继承自Handler

源码如下

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

这里的onHandleIntent是一个抽象方法,示例JobService中实现了该方法,log信息也是在这里输出的。

可以看出,onHandleIntent方法之后会调用ServicestopSelf方法来停止服务。

接下来分析mServiceHandler.sendMessage(msg)onHandleIntent((Intent)msg.obj)之间的执行内容。

ServiceHandler

ServiceHandlersendMessage方法最终会调用到它的enqueueMessage方法,源码如下

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
        msg.target = this;
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
    }

从这里可以发现Handler使用了一个MessageQueue对象来保存msg,而MessageQueue实例是属于Handler

下面分析下ServiceHandler的实例化,源码如下

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

从上面源码中可以看到ServiceHandlerLooper实例来自HandlerThread对象,先来看下handlerThread的源码。

HandlerThread

HandlerThread继承自Thread,下面是它的run方法源码

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

Looper

下面是Looperprepare方法

public static void prepare() {
        prepare(true);
    }
    private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }

prepare方法中使用sThreadLocal来存储Looper对象,保证了Looper对象是线程私有的。

接下来看run方法中的Looper.loop方法

public static void loop() {
        final Looper me = myLooper();
        ...
        final MessageQueue queue = me.mQueue;
        Binder.clearCallingIdentity();
        final long ident = Binder.clearCallingIdentity();
        for (;;) {
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }
          ...
            final long slowDispatchThresholdMs = me.mSlowDispatchThresholdMs;
       ...  
            final long start = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
            final long end;
            try {
                msg.target.dispatchMessage(msg);
                end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
            } finally {
                if (traceTag != 0) {
                    Trace.traceEnd(traceTag);
                }
            }
         ...
            msg.recycleUnchecked();
        }
    }

loop方法的功能主要用来分发MessageQueue链表中存储的Message。顺便说明一下msg.recycleUnchecked()方法用来重置msg,方便后续调用Handler.obtainMessage方法时进行复用。

接下来分析下msg.target.dispatchMessage(msg);

从上面ServiceHandlerenqueueMessage代码中可以了解到,这里的target就是ServiceHandler实例。

直接来看HandlerdispatchMessage源码

public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

这里的handleMessage是一个空实现,需要Handler子类进行重写,比如ServiceHandler

@Override
        public void handleMessage(Message msg) {
            onHandleIntent((Intent)msg.obj);
            stopSelf(msg.arg1);
        }

这就是从mServiceHandler.sendMessage(msg)onHandleIntent((Intent)msg.obj)的代码执行流程。

MessageQueue

以上流程中关于MessageQueue保存Message对象没有深入分析,这里做个补充

下面的MessageQueueenqueueMessage方法源码

boolean enqueueMessage(Message msg, long when) {
      ...
        synchronized (this) {
            if (mQuitting) {
                IllegalStateException e = new IllegalStateException(
                        msg.target + " sending message to a Handler on a dead thread");
                Log.w(TAG, e.getMessage(), e);
                msg.recycle();
                return false;
            }
            msg.markInUse();
            msg.when = when;
            Message p = mMessages;
            boolean needWake;
          // 在链表头插入msg
            if (p == null || when == 0 || when < p.when) {
                // New head, wake up the event queue if blocked.
                msg.next = p;
                mMessages = msg;
                needWake = mBlocked;
            }
          // 按执行时间顺序插入msg
          else {
                needWake = mBlocked && p.target == null && msg.isAsynchronous();
                Message prev;
                for (;;) {
                    prev = p;
                    p = p.next;
                    if (p == null || when < p.when) {
                        break;
                    }
                    if (needWake && p.isAsynchronous()) {
                        needWake = false;
                    }
                }
                msg.next = p; // invariant: p == prev.next
                prev.next = msg;
            }
            // We can assume mPtr != 0 because mQuitting is false.
            if (needWake) {
                nativeWake(mPtr);
            }
        }
        return true;
    }

从上面代码可以了解到,Message的插入操作主要分两种情况,一种是调用没有指定执行时间的,直接在表头插入,另一种是指定执行时间的,需要按执行时间顺序进行插入。

以上就是IntentService代码的整个执行流程。

    原文作者:Android源码分析
    原文地址: https://juejin.im/entry/5a2613216fb9a044fd119c6f
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞