Service组件在新进程中的启动过程主要过程如下所示:
1.Client组件向AMS发送一个启动Server组件的进程间通信请求
2.AMS发现用来运行Server组件的应用程序进程不存在,先将Server组件的信息保存下来,接着创建一个新的应用程序进程
3.新进程启动完成后向AMS发送一个启动完成的进程间通信请求,以便AMS可以继续启动Server组件的操作。
4.AMS将第二步保存下来的Server组件信息发送给第二步创建的应用程序进程,将Server组件启动起来。
1.ContextWrapper.startService
代码路径:/frameworks/base/core/java/android/content/ContextWrapper.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/content/ContextWrapper.java)
642 @Override 643 public ComponentName startService(Intent service) { 644 return mBase.startService(service); 645 }
要启动Service,会调用startService方法,它的实现在ContextWrapper中
2.ContextImpl.startService
代码路径:/frameworks/base/core/java/android/app/ContextImpl.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/ContextImpl.java)
1458 @Override 1459 public ComponentName startService(Intent service) { 1460 warnIfCallingFromSystemProcess(); 1461 return startServiceCommon(service, false, mUser); 1462 }
startService方法中会return startServiceCommon方法
3.ContextImpl.startServiceCommon
代码路径:/frameworks/base/core/java/android/app/ContextImpl.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/ContextImpl.java)1486 private ComponentName startServiceCommon(Intent service, boolean requireForeground, 1487 UserHandle user) { 1488 try { 1489 validateServiceIntent(service); 1490 service.prepareToLeaveProcess(this); 1491 ComponentName cn = ActivityManager.getService().startService( 1492 mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded( 1493 getContentResolver()), requireForeground, 1494 getOpPackageName(), user.getIdentifier()); 1495 if (cn != null) { 1496 if (cn.getPackageName().equals("!")) { 1497 throw new SecurityException( 1498 "Not allowed to start service " + service 1499 + " without permission " + cn.getClassName()); 1500 } else if (cn.getPackageName().equals("!!")) { 1501 throw new SecurityException( 1502 "Unable to start service " + service 1503 + ": " + cn.getClassName()); 1504 } else if (cn.getPackageName().equals("?")) { 1505 throw new IllegalStateException( 1506 "Not allowed to start service " + service + ": " + cn.getClassName()); 1507 } 1508 } 1509 return cn; 1510 } catch (RemoteException e) { 1511 throw e.rethrowFromSystemServer(); 1512 } 1513 }
在startServiceCommon方法中会在1491行调用ActivityManageService(AMS)的代理对象的startService方法,最终会调用AMS的startService方法
这里与Android 7.0代码的逻辑有些不同,Android 7.0是通过ActivityManagerNative的getDefault来获取AMS的代理对象,现在这个逻辑封装到了ActivityManager中而不是ActivityManagerNative中
4.ActivityManagerService.startService
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java)18124 @Override 18125 public ComponentName startService(IApplicationThread caller, Intent service, 18126 String resolvedType, boolean requireForeground, String callingPackage, int userId) 18127 throws TransactionTooLargeException { 18128 enforceNotIsolatedCaller("startService"); 18129 // Refuse possible leaked file descriptors 18130 if (service != null && service.hasFileDescriptors() == true) { 18131 throw new IllegalArgumentException("File descriptors passed in Intent"); 18132 } 18133 18134 if (callingPackage == null) { 18135 throw new IllegalArgumentException("callingPackage cannot be null"); 18136 } 18137 18138 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, 18139 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground); 18140 synchronized(this) { 18141 final int callingPid = Binder.getCallingPid(); 18142 final int callingUid = Binder.getCallingUid(); 18143 final long origId = Binder.clearCallingIdentity(); 18144 ComponentName res; 18145 try { 18146 res = mServices.startServiceLocked(caller, service, 18147 resolvedType, callingPid, callingUid, 18148 requireForeground, callingPackage, userId); 18149 } finally { 18150 Binder.restoreCallingIdentity(origId); 18151 } 18152 return res; 18153 } 18154 }
在18146行调用mServices的startServiceLocked方法,mServices的类型是ActiveServices(1023行定义的mServices)
5.ActiveServices.startServiceLocked
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java)327 ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, 328 int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId) 329 throws TransactionTooLargeException { ................................................... 477 478 ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting); 479 return cmp; 480 }
............................................................................
526 ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r, 527 boolean callerFg, boolean addToStarting) throws TransactionTooLargeException { 528 ServiceState stracker = r.getTracker(); 529 if (stracker != null) { 530 stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity); 531 } 532 r.callStart = false; 533 synchronized (r.stats.getBatteryStats()) { 534 r.stats.startRunningLocked(); 535 } 536 String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false); 537 if (error != null) { 538 return new ComponentName("!!", error); 539 } 540 541 if (r.startRequested && addToStarting) { 542 boolean first = smap.mStartingBackground.size() == 0; 543 smap.mStartingBackground.add(r); 544 r.startingBgTimeout = SystemClock.uptimeMillis() + mAm.mConstants.BG_START_TIMEOUT; 545 if (DEBUG_DELAYED_SERVICE) { 546 RuntimeException here = new RuntimeException("here"); 547 here.fillInStackTrace(); 548 Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r, here); 549 } else if (DEBUG_DELAYED_STARTS) { 550 Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r); 551 } 552 if (first) { 553 smap.rescheduleDelayedStartsLocked(); 554 } 555 } else if (callerFg || r.fgRequired) { 556 smap.ensureNotStartingBackgroundLocked(r); 557 } 558 559 return r.name; 560 }
startServiceLocked方法的末尾478行return了startServiceInnerLocked方法;
startServiceInnerLocked方法中在536行又调用了bringUpServiceLocked方法
6.ActiveServices.bringUpServiceLocked
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java)2052 private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, 2053 boolean whileRestarting, boolean permissionsReviewRequired) 2054 throws TransactionTooLargeException { ............................................... 2107 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0; 2108 final String procName = r.processName; 2109 String hostingType = "service"; 2110 ProcessRecord app; 2111 2112 if (!isolated) { 2113 app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false); 2114 if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid 2115 + " app=" + app); 2116 if (app != null && app.thread != null) { 2117 try { 2118 app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats); 2119 realStartServiceLocked(r, app, execInFg); 2120 return null; 2121 } catch (TransactionTooLargeException e) { 2122 throw e; 2123 } catch (RemoteException e) { 2124 Slog.w(TAG, "Exception when starting service " + r.shortName, e); 2125 } 2126 2127 // If a dead object exception was thrown -- fall through to 2128 // restart the application. 2129 } 2130 } else { 2131 // If this service runs in an isolated process, then each time 2132 // we call startProcessLocked() we will get a new isolated 2133 // process, starting another process if we are currently waiting 2134 // for a previous process to come up. To deal with this, we store 2135 // in the service any current isolated process it is running in or 2136 // waiting to have come up. 2137 app = r.isolatedProc; 2138 if (WebViewZygote.isMultiprocessEnabled() 2139 && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) { 2140 hostingType = "webview_service"; 2141 } 2142 } 2143 2144 // Not running -- get it started, and enqueue this service record 2145 // to be executed when the app comes up. 2146 if (app == null && !permissionsReviewRequired) { 2147 if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags, 2148 hostingType, r.name, false, isolated, false)) == null) { 2149 String msg = "Unable to launch app " 2150 + r.appInfo.packageName + "/" 2151 + r.appInfo.uid + " for service " 2152 + r.intent.getIntent() + ": process is bad"; 2153 Slog.w(TAG, msg); 2154 bringDownServiceLocked(r); 2155 return msg; 2156 } 2157 if (isolated) { 2158 r.isolatedProc = app; 2159 } 2160 } 2161
.......................................
2175 2176 return null; 2177 }
在2108行得到ServiceRecord的processName的值赋值给procName ,其中ServiceRecord用来描述Service的android:process属性。
在2113行将procName和Service的uid传入到AMS的getProcessRecordLocked方法中,来查询是否存在一个与Service对应的ProcessRecord类型的对象app,ProcessRecord主要用来记录运行的应用程序进程的信息。
在2146行判断Service对应的app为null则说明用来运行Service的应用程序进程不存在,则调用在2146行的AMS的startProcessLocked方法来创建对应的应用程序进程。
在2116行判断如果用来运行Service的应用程序进程存在,则调用2119行的realStartServiceLocked方法。
7.ActiveServices.realStartServiceLocked
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java)2189 private final void realStartServiceLocked(ServiceRecord r, 2190 ProcessRecord app, boolean execInFg) throws RemoteException { ................................. 2207 try { 2208 if (LOG_SERVICE_START_STOP) { 2209 String nameTerm; 2210 int lastPeriod = r.shortName.lastIndexOf('.'); 2211 nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName; 2212 EventLogTags.writeAmCreateService( 2213 r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid); 2214 } 2215 synchronized (r.stats.getBatteryStats()) { 2216 r.stats.startLaunchedLocked(); 2217 } 2218 mAm.notifyPackageUse(r.serviceInfo.packageName, 2219 PackageManager.NOTIFY_PACKAGE_USE_SERVICE); 2220 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE); 2221 app.thread.scheduleCreateService(r, r.serviceInfo, 2222 mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), 2223 app.repProcState); 2224 r.postNotification(); 2225 created = true; 2226 } catch (DeadObjectException e) { 2227 Slog.w(TAG, "Application dead when creating service " + r); 2228 mAm.appDiedLocked(app); 2229 throw e; 2230 } finally { 2231 if (!created) { 2232 // Keep the executeNesting count accurate. 2233 final boolean inDestroying = mDestroyingServices.contains(r); 2234 serviceDoneExecutingLocked(r, inDestroying, inDestroying); 2235 2236 // Cleanup. 2237 if (newService) { 2238 app.services.remove(r); 2239 r.app = null; 2240 } 2241 2242 // Retry. 2243 if (!inDestroying) { 2244 scheduleServiceRestartLocked(r, false); 2245 } 2246 } 2247 } 2248 ............................................ 2282 }
在realStartServiceLocked方法中调用了2221行的app.thread的scheduleCreateService方法。
其中app.thread是IApplicationThread类型的,它的实现是ActivityThread的内部类ApplicationThread,其中ApplicationThread继承了ApplicationThreadNative,而ApplicationThreadNative继承了Binder并实现了IApplicationThread接口。
8.ActivityThread.scheduleCreateService
代码路径:/frameworks/base/core/java/android/app/ActivityThread.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/ActivityThread.java)841 public final void scheduleCreateService(IBinder token, 842 ServiceInfo info, CompatibilityInfo compatInfo, int processState) { 843 updateProcessState(processState, false); 844 CreateServiceData s = new CreateServiceData(); 845 s.token = token; 846 s.info = info; 847 s.compatInfo = compatInfo; 848 849 sendMessage(H.CREATE_SERVICE, s); 850 }
首先将要启动的信息封装成CreateServiceData 对象并传给sendMessage方法,sendMessage方法向H发送CREATE_SERVICE消息,H是ActivityThread的内部类并继承Handler。这个过程和根Activity启动过程是类似的。我们接着查看H的handleMessage方法。
9.ActivityThread.handleMessage
代码路径:/frameworks/base/core/java/android/app/ActivityThread.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/ActivityThread.java)1584 public void handleMessage(Message msg) { 1585 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); 1586 switch (msg.what) { ................................................ 1681 case CREATE_SERVICE: 1682 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj))); 1683 handleCreateService((CreateServiceData)msg.obj); 1684 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1685 break; ................................................ 1859 } 1860 Object obj = msg.obj; 1861 if (obj instanceof SomeArgs) { 1862 ((SomeArgs) obj).recycle(); 1863 } 1864 if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what)); 1865 }
在1683行handleMessage方法根据消息类型,调用了handleCreateService方法
10.ActivityThread.handleCreateService
代码路径:/frameworks/base/core/java/android/app/ActivityThread.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/ActivityThread.java)3376 private void handleCreateService(CreateServiceData data) { 3377 // If we are getting ready to gc after going to the background, well 3378 // we are back active so skip it. 3379 unscheduleGcIdler(); 3380 3381 LoadedApk packageInfo = getPackageInfoNoCheck( 3382 data.info.applicationInfo, data.compatInfo); 3383 Service service = null; 3384 try { 3385 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 3386 service = (Service) cl.loadClass(data.info.name).newInstance(); 3387 } catch (Exception e) { 3388 if (!mInstrumentation.onException(service, e)) { 3389 throw new RuntimeException( 3390 "Unable to instantiate service " + data.info.name 3391 + ": " + e.toString(), e); 3392 } 3393 } 3394 3395 try { 3396 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name); 3397 3398 ContextImpl context = ContextImpl.createAppContext(this, packageInfo); 3399 context.setOuterContext(service); 3400 3401 Application app = packageInfo.makeApplication(false, mInstrumentation); 3402 service.attach(context, this, data.info.name, data.token, app, 3403 ActivityManager.getService()); 3404 service.onCreate(); 3405 mServices.put(data.token, service); 3406 try { 3407 ActivityManager.getService().serviceDoneExecuting( 3408 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); 3409 } catch (RemoteException e) { 3410 throw e.rethrowFromSystemServer(); 3411 } 3412 } catch (Exception e) { 3413 if (!mInstrumentation.onException(service, e)) { 3414 throw new RuntimeException( 3415 "Unable to create service " + data.info.name 3416 + ": " + e.toString(), e); 3417 } 3418 } 3419 }
在3381行获取要启动Service的应用程序的LoadedApk,LoadedApk是一个APK文件的描述类。
在3385行通过调用LoadedApk的getClassLoader方法来获取类加载器。
在3386行根据CreateServiceData对象中存储的Service信息,将Service加载到内存中。
在3398行创建Service的上下文环境ContextImpl对象。
在3402行通过Service的attach方法来初始化Service。
在3404行调用Service的onCreate方法,这样Service就启动了。
在3405行将启动的Service加入到ActivityThread的成员变量mServices中,其中mServices是ArrayMap类型。
240 final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();