Android(安卓)Service 启动流程
概述
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.thread
是IApplicationThread
类型的,他的实现是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
,这个Handler
是ActivityThread
的内部类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
出新的进程,进出新进程的ActivityThread
的main
方法- 新进程通过
Binder
向syster_server
进程发起attachApplication
请求 syster_server
进程收到请求后,进过一系列的准备后,通过Binder
向新进程发送scheduleCreateService
请求- 新进程收到请求后,通过
Handler
发送CREATE_SERVICE
消息 - 主线程收到message,创建
Service
,并回调onCreate
更多相关文章
- 一款霸榜 GitHub 的开源 Linux 资源监视器!
- Android通知栏学习(基础篇)
- Android学习笔记之获得屏幕属性DisplayMetrics
- Android(安卓)build文件的删除的方法
- 正确的Flutter和Android交互代码
- android添加以太网ethernet方法 android框架添加
- MediaScanner源码分析
- Android(安卓)Camera预览左右上下镜像
- Fragment与Activity之间数据交互(Kotlin)