Service启动流程

Android Service启动流程

概述

Service是android系统非常重要的四大组件之一,Service通常被用来在后台做一些耗时任务。本文从源码角度讲述启动Service流程

启动流程

1 startService

@Override
public ComponentName startService(Intent service) {
    return mBase.startService(service);
}  

2 [-> ContextImpl.java]

class ContextImpl extends Context {
     @Override
    public ComponentName startService(Intent service) {
        warnIfCallingFromSystemProcess();
        return startServiceCommon(service, false, mUser);
    }
}

3 [-> ContextImpl.java]

private ComponentName startServiceCommon(Intent service, UserHandle user) {
    try {
        //检验service,当service为空则throw异常
        validateServiceIntent(service);
        service.prepareToLeaveProcess();
        // 调用ActivityManagerNative类 【见流程3.1以及流程4】
        ComponentName cn = ActivityManagerNative.getDefault().startService(
            mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver()), getOpPackageName(), user.getIdentifier());
        if (cn != null) {
            if (cn.getPackageName().equals("!")) {
                throw new SecurityException("Not allowed to start service " +
                    service + " without permission " + cn.getClassName());
            } else if (cn.getPackageName().equals("!!")) {
                throw new SecurityException("Unable to start service " +
                    service  ": " + cn.getClassName());
            }
        }
        return cn;
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
}

``
这里通过ActivityManager.getService().startService() 是通过binder机制发起了服务请求,这里假设startService的发起进程为A,ActivityManagerService为进程B,那么进程A通过Binder机制(采用IActivityManager接口)向进程B发起请求服务,进程B则通过Binder机制(采用IApplicationThread接口)向进程A发起请求服务。也就是说进程A和进程B通过binder机制可以互相主动发起请求来进行进程间通信 

4.ActivityManager

@Override
public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType, String callingPackage, int userId) throws TransactionTooLargeException {
    //当调用者是孤立进程,则抛出异常。
    enforceNotIsolatedCaller("startService");

    if (service != null && service.hasFileDescriptors() == true) {
        throw new IllegalArgumentException("File descriptors passed in Intent");
    }
    if (callingPackage == null) {
        throw new IllegalArgumentException("callingPackage cannot be null");
    }
    if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
            "startService: " + service + " type=" + resolvedType);

    synchronized(this) {
        final int callingPid = Binder.getCallingPid(); //调用者pid
        final int callingUid = Binder.getCallingUid(); //调用者uid
        final long origId = Binder.clearCallingIdentity();
        //此次的mServices为ActiveServices对象 【见流程5】
        ComponentName res = mServices.startServiceLocked(caller, service,
                resolvedType, callingPid, callingUid, callingPackage, userId);
        Binder.restoreCallingIdentity(origId);
        return res;
    }
}

这里mServices.startServiceLocked() 中的mServices是ActiveServices的实例

5 ActiveServices.startServiceLocked

ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid, String callingPackage, int userId) throws TransactionTooLargeException {

    final boolean callerFg;
    if (caller != null) {
        final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
        if (callerApp == null)
            throw new SecurityException(""); //抛出异常,此处省略异常字符串
        callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
    } else {
        callerFg = true;
    }
    //检索服务信息
    ServiceLookupResult res =  retrieveServiceLocked(service, resolvedType, callingPackage,
                callingPid, callingUid, userId, true, callerFg);
    if (res == null) {
        return null;
    }
    if (res.record == null) {
        return new ComponentName("!", res.permission != null
                ? res.permission : "private to package");
    }
    ServiceRecord r = res.record;
    if (!mAm.getUserManagerLocked().exists(r.userId)) { //检查是否存在启动服务的user
        return null;
    }
    NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
            callingUid, r.packageName, service, service.getFlags(), null, r.userId);

    r.lastActivity = SystemClock.uptimeMillis();
    r.startRequested = true;
    r.delayedStop = false;
    r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
            service, neededGrants));
    final ServiceMap smap = getServiceMap(r.userId);
    boolean addToStarting = false;
    //对于非前台进程的调度
    if (!callerFg && r.app == null && mAm.mStartedUsers.get(r.userId) != null) {
        ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
        if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
            if (r.delayed) {  //已计划延迟启动
                return r.name;
            }
            if (smap.mStartingBackground.size() >= mMaxStartingBackground) {
                //当超出 同一时间允许后续启动的最大服务数,则将该服务加入延迟启动的队列。
                smap.mDelayedStartList.add(r);
                r.delayed = true;
                return r.name;
            }
            addToStarting = true;
        } else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
            //将新的服务加入到后台启动队列,该队列也包含当前正在运行其他services或者receivers的进程
            addToStarting = true;
        }
    }
    //【见流程6】
    return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}

这个方法最后调用的是startServiceInnerLocked

6.ActiveServices.startServiceLocked


 ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
            boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
       ProcessStats.ServiceState stracker = r.getTracker();
    if (stracker != null) {
        stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
    }
    r.callStart = false;
    synchronized (r.stats.getBatteryStats()) {
        r.stats.startRunningLocked(); //用于耗电统计,开启运行的状态
    }
    //【见流程7】
    String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
    if (error != null) {
        return new ComponentName("!!", error);
    }
    if (r.startRequested && addToStarting) {
        boolean first = smap.mStartingBackground.size() == 0;
        smap.mStartingBackground.add(r);
        r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
        if (first) {
            smap.rescheduleDelayedStarts();
        }
    } else if (callerFg) {
        smap.ensureNotStartingBackground(r);
    }
    return r.name;

7.ActiveServices.bringUpServiceLocked

private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting) throws TransactionTooLargeException {
    if (r.app != null && r.app.thread != null) {
        //调用service.onStartCommand()过程
        sendServiceArgsLocked(r, execInFg, false);
        return null;
    }
    if (!whileRestarting && r.restartDelay > 0) {
        return null; //等待延迟重启的过程,则直接返回
    }

    // 启动service前,把service从重启服务队列中移除
    if (mRestartingServices.remove(r)) {
        r.resetRestartCounter();
        clearRestartingIfNeededLocked(r);
    }
    //service正在启动,将delayed设置为false
    if (r.delayed) {
        getServiceMap(r.userId).mDelayedStartList.remove(r);
        r.delayed = false;
    }

    //确保拥有该服务的user已经启动,否则停止;
    if (mAm.mStartedUsers.get(r.userId) == null) {
        String msg = "";
        bringDownServiceLocked(r);
        return msg;
    }
    //服务正在启动,设置package停止状态为false
    AppGlobals.getPackageManager().setPackageStoppedState(
            r.packageName, false, r.userId);

    final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
    final String procName = r.processName;
    ProcessRecord app;
    if (!isolated) {
        //根据进程名和uid,查询ProcessRecord
        app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
        if (app != null && app.thread != null) {
            try {
                app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
                // 启动服务 【见流程8】
                realStartServiceLocked(r, app, execInFg);
                return null;
            } catch (TransactionTooLargeException e) {
                throw e;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting service " + r.shortName, e);
            }
        }
    } else {
        app = r.isolatedProc;
    }

    //对于进程没有启动的情况
    if (app == null) {
        //启动service所要运行的进程(7.1)
        if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                "service", r.name, false, isolated, false)) == null) {
            String msg = ""
            bringDownServiceLocked(r); // 进程启动失败
            return msg;
        }
        if (isolated) {
            r.isolatedProc = app;
        }
    }
    if (!mPendingServices.contains(r)) {
        mPendingServices.add(r);
    }
    if (r.delayedStop) {
        r.delayedStop = false;
        if (r.startRequested) {
            stopServiceLocked(r); //停止服务
        }
    }
    return null;
}

这里判断app != null && app.thread != null 如果不为空,说明进程已经启动起来了,直接调用realStartServiceLocked启动服务,如果进程没有启动,则调用AMS.startProcessLocked启动进程

7.AMS.startProcessLocked

 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
                null /* entryPoint */, null /* entryPointArgs */);

AMS.startProcessLocked方法最后会调用到ActivityService.attachApplicationLocked

8.1 ActivityService.attachApplicationLocked


boolean didSomething = false;
    //启动mPendingServices队列中,等待在该进程启动的服务
    if (mPendingServices.size() > 0) {
        ServiceRecord sr = null;
        try {
            for (int i=0; i 0) {
        ServiceRecord sr = null;
        for (int i=0; i

9. ActivityService.AS.realStartServiceLocked

private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException {
    ...

    r.app = app;
    r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
    final boolean newService = app.services.add(r);

    //发送delay消息【见流程9.1】
    bumpServiceExecutingLocked(r, execInFg, "create");
    mAm.updateLruProcessLocked(app, false, null);
    mAm.updateOomAdjLocked();
    boolean created = false;
    try {
        synchronized (r.stats.getBatteryStats()) {
            r.stats.startLaunchedLocked();
        }
        mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
        app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
        //服务进入 onCreate() 【见流程10】
        app.thread.scheduleCreateService(r, r.serviceInfo,
                mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                app.repProcState);
        r.postNotification();
        created = true;
    } catch (DeadObjectException e) {
        mAm.appDiedLocked(app); //应用死亡处理
        throw e;
    } finally {
        if (!created) {
            final boolean inDestroying = mDestroyingServices.contains(r);
            serviceDoneExecutingLocked(r, inDestroying, inDestroying);
            if (newService) {
                app.services.remove(r);
                r.app = null;
            }
            //尝试重新启动服务
            if (!inDestroying) {
                scheduleServiceRestartLocked(r, false);
            }
        }
    }
    requestServiceBindingsLocked(r, execInFg);
    updateServiceClientActivitiesLocked(app, null, true);

    if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
        r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                null, null));
    }
    //服务 进入onStartCommand() 【见流程17】
    sendServiceArgsLocked(r, execInFg, true);
    if (r.delayed) {
        getServiceMap(r.userId).mDelayedStartList.remove(r);
        r.delayed = false;
    }
    if (r.delayedStop) {
        r.delayedStop = false;
        if (r.startRequested) {
            stopServiceLocked(r); //停止服务
        }
    }
}


这个方法里面调用了app.thread.scheduleCreateService的scheduleCreateService, 这里的app.thread其实是IApplicationThread接口,也就是说在AS这个服务器进程中通过binder机制 (采用IApplicationThread接口)调用app进程的scheduleCreateService

10. ApplicationThread.scheduleCreateService

private class ApplicationThread extends IApplicationThread.Stub {
     public final void scheduleCreateService(IBinder token,
                ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
            updateProcessState(processState, false);
            CreateServiceData s = new CreateServiceData();
            s.token = token;
            s.info = info;
            s.compatInfo = compatInfo;

            sendMessage(H.CREATE_SERVICE, s);
        }
}


在ActivityThread的内部类ApplicationThread中通过Handler发送CREATE_SERVICE消息

11 ActivityThread.handleMessage

public void handleMessage(Message msg) {
    switch (msg.what) {
        ...
        case CREATE_SERVICE:
            handleCreateService((CreateServiceData)msg.obj); //【见流程15】
            break;
        case BIND_SERVICE:
            handleBindService((BindServiceData)msg.obj);
            break;
        case UNBIND_SERVICE:
            handleUnbindService((BindServiceData)msg.obj);
            break;
        case SERVICE_ARGS:
            handleServiceArgs((ServiceArgsData)msg.obj);  // serviceStart
            break;
        case STOP_SERVICE:
            handleStopService((IBinder)msg.obj);
            maybeSnapshot();
            break;
        ...
    }
}

12 ActivityThread.handleCreateService

//当应用处于后台即将进行GC,而此时被调回到活动状态,则跳过本次gc。
    unscheduleGcIdler();
    LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);

    java.lang.ClassLoader cl = packageInfo.getClassLoader();
    //通过反射创建目标服务对象
    Service service = (Service) cl.loadClass(data.info.name).newInstance();
    ...

    try {
        //创建ContextImpl对象
        ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
        context.setOuterContext(service);
        //创建Application对象,如果已创建,则不会再创建
        Application app = packageInfo.makeApplication(false, mInstrumentation);
        service.attach(context, this, data.info.name, data.token, app,
                ActivityManagerNative.getDefault());
        //调用服务onCreate()方法 【见流程13.1】
        service.onCreate();
        mServices.put(data.token, service);
        //调用服务创建完成
        ActivityManagerNative.getDefault().serviceDoneExecuting(
                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
    } catch (Exception e) {
        ...
    }


13 Service.onCreate

public abstract class Service extends ContextWrapper implements ComponentCallbacks2 {
    public void onCreate(){    }
}

至此Service的生命周期方法onCreate就开始执行了

总结

根据以上源代码流程分析可以得出,service启动流程

从关键代码流程来看:

1.ContextImpl.startService()
2.ActivityManagerProxy.startService() (ActivityManagerProxy和ActivityManangerService都实现了IActivityManager接口)
3.ActivityManagerNative.transact() => 通过Binder方式(采用IActivityManager接口调用ActivityManangerService)
4.ActivityManangerService.startService()
5.ApplicationThreadProxy.scheduleCreateService()
6.ApplicationThreadNative.onTransact
7.ApplicationThreadNative. scheduleCreateService
8.ApplicationThread. scheduleCreateService=>通过Binder方式(采用IApplicaitonThread接口)
9.ActivityThread.mH.sendMessage()
10.ActivityThread.handleCreateService();
11.创建application(只会创建一次)
12.反射创建Service,调用其onCreate方法

从进程方面来看

在整个startService启动过程中,共涉及到以下几个进程

  • Process A进程,是指调用startService命令所在的进程,也就是启动服务所在的进程,例如点击桌面app图标,此处Process A便是Launch所在进程
  • system_server进程:系统进程,例如ApplicationThreadProxy,ActivityManagerService都运行在system_server进程的不同线程中
  • Zygote进程:由init进程孵化而来
  • Remote Service进程: 远程服务所在进程,由system_server进程孵化而来,主线程负责Activity/Service/BroadcastReceiver 以及ui操作等的生命周期调用,另外每个app进程至少会有两个binder线程ApplicationThread(简称AT)和ActivityManagerProxy(简称AMP)
2222.jpeg

参考资料

GitYuan博客:startService启动过程分析

你可能感兴趣的:(Service启动流程)