概述

Service启动流程和Activity启动流程有些相似,不了解Activity启动流程的可以看我之前的一篇博客Android App启动过程

Start Service 流程

Context.startService()

首先我们先从 context.startService()这个方法为起点进行分析,我们看下他的源码

## ContextWrapper.javapublic class ContextWrapper extends Context {    public ComponentName startService(Intent service) {        return mBase.startService(service); //其中mBase为ContextImpl对象     }}

这个方法又调用了ContextImpl.startService

## ContextImpl.javaclass ContextImpl extends Context {    @Override    public ComponentName startService(Intent service) {        warnIfCallingFromSystemProcess();        return startServiceCommon(service, mUser);     }        private ComponentName startServiceCommon(Intent service, UserHandle user) {    try {    ...        ComponentName cn = ActivityManagerNative.getDefault().startService(            mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver()), getOpPackageName(), user.getIdentifier());   ...        return cn;    } catch (RemoteException e) {        throw new RuntimeException("Failure from system", e);    }}

我们看到最后调用了ActivityManagerNative.getDefault().startService,其中ActivityManagerNative.getDefault()就是ActivityManagerService,这时就完成了从调用进程system_server进程,其中是通过Binder传输的信息

AMS.startService

下面我们看一下AMS到底做了什么

 ## ActivityManagerService.java public ComponentName startService(IApplicationThread caller, Intent service,            String resolvedType, boolean requireForeground, String callingPackage, int userId)            throws TransactionTooLargeException {        ····        synchronized(this) {            final int callingPid = Binder.getCallingPid();            final int callingUid = Binder.getCallingUid();            final long origId = Binder.clearCallingIdentity();            ComponentName res;            try {                res = mServices.startServiceLocked(caller, service,                        resolvedType, callingPid, callingUid,                        requireForeground, callingPackage, userId);            } finally {                Binder.restoreCallingIdentity(origId);            }            return res;        }    }

这个方法又调用了ActivityService#startServiceLocked

    ## ActivityService.java    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,            int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)            throws TransactionTooLargeException {                        ···        ServiceLookupResult res =            retrieveServiceLocked(service, resolvedType, callingPackage,                    callingPid, callingUid, userId, true, callerFg, false, false);        if (res == null) {            return null;        }        if (res.record == null) {            return new ComponentName("!", res.permission != null                    ? res.permission : "private to package");        }        ServiceRecord r = res.record;        ···        ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);        return cmp;        }                                    

继续调用了ActivityService#startServiceInnerLocked

 ## ActivityService.java ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,            boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {        ···        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);        if (error != null) {            return new ComponentName("!!", error);        }        ···        return r.name;    }

继续调用了ActivityService#bringUpServiceLocked

  private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,            boolean whileRestarting, boolean permissionsReviewRequired)            throws TransactionTooLargeException {                     ···        if (!isolated) {            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);            if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid                        + " app=" + app);            //如果Service进程存在            if (app != null && app.thread != null) {                try {                    app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);                    //启动Service                    realStartServiceLocked(r, app, execInFg);                    return null;                } catch (TransactionTooLargeException e) {                    throw e;                } catch (RemoteException e) {                    Slog.w(TAG, "Exception when starting service " + r.shortName, e);                }                // If a dead object exception was thrown -- fall through to                // restart the application.            }        }         //如果不存在此进程,则        if (app == null && !permissionsReviewRequired) {            //启动运行的线程            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,                    hostingType, r.name, false, isolated, false)) == null) {                String msg = "Unable to launch app "                        + r.appInfo.packageName + "/"                        + r.appInfo.uid + " for service "                        + r.intent.getIntent() + ": process is bad";                Slog.w(TAG, msg);                bringDownServiceLocked(r);                return msg;            }            if (isolated) {                r.isolatedProc = app;            }        }        return null;    }

这个方法主要做了俩件事

  • 如果Service进程已经存在,则直接调用realStartServiceLocked
  • 如果Service进程不存在,则直接执行startProcessLocked方法创建进程,进过层层的调用,最终会调用到AMS.attachApplicationLocked方法,然后执行realStartServiceLocked方法

AMS.attachApplicationLocked

private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {    ...    thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,            profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,            app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,            isRestrictedBackupMode || !normalMode, app.persistent,            new Configuration(mConfiguration), app.compat,            getCommonServicesLocked(app.isolated),            mCoreSettingsObserver.getCoreSettingsLocked());    ...    if (!badApp) {        try {            //寻找所有需要在该进程中运行的服务             didSomething |= mServices.attachApplicationLocked(app, processName);        } catch (Exception e) {            badApp = true;        }    }    ...    return true;}

继续调用 AS.attachApplicationLocked

 boolean attachApplicationLocked(ProcessRecord proc, String processName)            throws RemoteException {        boolean didSomething = false;        ...        if (mPendingServices.size() > 0) {            ServiceRecord sr = null;            try {                for (int i=0; i<mPendingServices.size(); i++) {                    sr = mPendingServices.get(i);                    if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid                            || !processName.equals(sr.processName))) {                        continue;                    }                    mPendingServices.remove(i);                    i--;                    proc.addPackage(sr.appInfo.packageName, sr.appInfo.longVersionCode,                            mAm.mProcessStats);                    //启动Service                    realStartServiceLocked(sr, proc, sr.createdFromFg);                    didSomething = true;                  ...                }                  }

这个方法调用了realStartServiceLocked

    private final void realStartServiceLocked(ServiceRecord r,            ProcessRecord app, boolean execInFg) throws RemoteException {          ...          app.thread.scheduleCreateService(r, r.serviceInfo,                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),                    app.repProcState);            r.postNotification();            created = true;                        ...                }

这个方法内部调用了app.thread.scheduleCreateService,而app.threadIApplicationThread类型的,他的实现是ActivityThread的内部类ApplicationThread是一个Binder,下面我们看一下ApplicationThread#scheduleCreateService这个方法

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

这个方法其实是发送了一个消息给Handler,这个HandlerActivityThread的内部类H

  class H extends Handler {   public void handleMessage(Message msg) {            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));            switch (msg.what) {                case CREATE_SERVICE:                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));                    handleCreateService((CreateServiceData)msg.obj);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                    break;                                        }                    }

最终调用了handleCreateService方法

 private void handleCreateService(CreateServiceData data) {         LoadedApk packageInfo = getPackageInfoNoCheck(                data.info.applicationInfo, data.compatInfo);        Service service = null;        try {            //获取类加载器            java.lang.ClassLoader cl = packageInfo.getClassLoader();            //加载Service实例            service = packageInfo.getAppFactory()                    .instantiateService(cl, data.info.name, data.intent);        }        try {            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);            //创建Service的Context            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);            context.setOuterContext(service);            Application app = packageInfo.makeApplication(false, mInstrumentation);            //初始化Service            service.attach(context, this, data.info.name, data.token, app,                    ActivityManager.getService());            //调用Service的onCreate方法            service.onCreate();            mServices.put(data.token, service);            try {                ActivityManager.getService().serviceDoneExecuting(                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);            } catch (RemoteException e) {                throw e.rethrowFromSystemServer();            }        } catch (Exception e) {            if (!mInstrumentation.onException(service, e)) {                throw new RuntimeException(                    "Unable to create service " + data.info.name                    + ": " + e.toString(), e);            }        }    }

到这里Service就启动完成了

总结

整个StartService过程,从进程的角度看Service的启动流程

  • ProcessA进程采用Binder形式向syster_server进程发起startService请求
  • syster_server进程收到请求后,向zygote进程发送创建进程的请求
  • zygote进程fork出新的进程,进出新进程的ActivityThreadmain方法
  • 新进程通过Bindersyster_server进程发起attachApplication请求
  • syster_server进程收到请求后,进过一系列的准备后,通过Binder向新进程发送scheduleCreateService请求
  • 新进程收到请求后,通过Handler发送CREATE_SERVICE消息
  • 主线程收到message,创建Service,并回调onCreate

更多相关文章

  1. 一款霸榜 GitHub 的开源 Linux 资源监视器!
  2. Android通知栏学习(基础篇)
  3. Android学习笔记之获得屏幕属性DisplayMetrics
  4. Android(安卓)build文件的删除的方法
  5. 正确的Flutter和Android交互代码
  6. android添加以太网ethernet方法 android框架添加
  7. MediaScanner源码分析
  8. Android(安卓)Camera预览左右上下镜像
  9. Fragment与Activity之间数据交互(Kotlin)

随机推荐

  1. Android应用程序资源管理器(Asset Manager
  2. Android:增强目录选择器对话框
  3. Android(安卓)- 支持不同的设备
  4. Android(安卓)Notification 详解,使用Medi
  5. 如何检索Android设备的唯一ID
  6. (Android实战系统二)Android网络互动传输
  7. 开发者大会传递信号:Android开发者将越来
  8. 安卓Android开发视频教程大全50GB/安卓基
  9. (转)Android内存管理机制之一:lowmemory k
  10. Android(安卓)Studio 使用jni