在编写Android应用程序时,我们一般将比较耗时的操作放在一个独立的进程来处理,这样主进程仍然可以流畅地响应界面事件,提高用户体验。Android系统为我们提供了一个Service类,我们可以实现一个以Service为基类的服务子类,在里面实现自己的计算型逻辑,然后在主进程通过startService函数来启动这个服务。在本文中,将详细分析应用程序进程是如何通过startService函数来启动自定义服务的。
frameworks\base\core\java\android\content\Context.java
public abstract ComponentName startService(Intent service);在Context类中定义了抽象方法startService,该函数由Context的子类ContextImpl实现。
frameworks\base\core\java\android\content\ContextWrapper.java
public ComponentName startService(Intent service) { return mBase.startService(service); }mBase为ContextImpl类型对象
frameworks\base\core\java\android\app\ContextImpl.java
public ComponentName startService(Intent service) { try { service.setAllowFds(false); //调用ActivityManagerService服务的Binder远程代理发送启动Service的参数 ComponentName cn = ActivityManagerNative.getDefault().startService( mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver())); if (cn != null && cn.getPackageName().equals("!")) { throw new SecurityException( "Not allowed to start service " + service + " without permission " + cn.getClassName()); } return cn; } catch (RemoteException e) { return null; } }ActivityManagerNative.getDefault()将得到ActivityManagerProxy对象,参数mMainThread.getApplicationThread()表示为当前启动服务进程的ApplicationThread对象,参数service.resolveTypeIfNeeded(getContentResolver())返回当前传输的Intent的MEMI号,关于Binder进程间RPC调用过程这里不在详细分析,有兴趣可以参考 Android服务函数远程调用源码分析。通过ActivityManagerNative.getDefault().startService()调用,将Service的启动交给SystemServer进程的ActivityManagerService服务来完成。
frameworks\base\services\java\com\android\server\am\ActivityManagerService.java
public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType) { // Refuse possible leaked file descriptors if (service != null && service.hasFileDescriptors() == true) { throw new IllegalArgumentException("File descriptors passed in Intent"); } synchronized(this) { //读取启动服务的应用程序进程的PID和UID final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); ComponentName res = startServiceLocked(caller, service, resolvedType, callingPid, callingUid); Binder.restoreCallingIdentity(origId); return res; } }
参数caller是启动服务的应用程序进程的ApplicationThread实例,比如说Launcher启动服务,那么这个caller就是Launcher进程的ApplicationThread实例,每一个Android应用程序进程都有且只有一个ActivityThread实例,每一个ActivityThread实例中又定义了一个ApplicationThread对象。接下来调用startServiceLocked函数来启动服务
frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid) { synchronized(this) { if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service + " type=" + resolvedType + " args=" + service.getExtras()); if (caller != null) { //通过ApplicationThread对象从ActivityManagerService的成员变量mLruProcesses列表中查找启动服务的进程在ActivityManagerService中的ProcessRecord对象,变量mLruProcesses的说明: /** * List of running applications, sorted by recent usage. * The first entry in the list is the least recently used. * It contains ApplicationRecord objects. This list does NOT include * any persistent application records (since we never want to exit them). */ final ProcessRecord callerApp = getRecordForAppLocked(caller); if (callerApp == null) { throw new SecurityException( "Unable to find app for caller " + caller + " (pid=" + Binder.getCallingPid() + ") when starting service " + service); } } //解析service这个Intent /** * private final class ServiceLookupResult { * final ServiceRecord record; ServiceRecord用于在服务端描述一个Service信息 * final String permission; * ServiceLookupResult(ServiceRecord _record, String _permission) { * record = _record; * permission = _permission; * } * }; */ ServiceLookupResult res = retrieveServiceLocked(service, resolvedType, callingPid, callingUid, UserId.getUserId(callingUid)); //系统中没有注册此Service if (res == null) { return null; } if (res.record == null) { return new ComponentName("!", res.permission != null ? res.permission : "private to package"); } //权限检查 ServiceRecord r = res.record; NeededUriGrants neededGrants = checkGrantUriPermissionFromIntentLocked( callingUid, r.packageName, service, service.getFlags(), null); if (unscheduleServiceRestartLocked(r)) { if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r); } //初始化服务端的ServiceRecord信息 r.startRequested = true; r.callStart = false; r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), service, neededGrants)); r.lastActivity = SystemClock.uptimeMillis(); synchronized (r.stats.getBatteryStats()) { r.stats.startRunningLocked(); } //进一步启动Service if (!bringUpServiceLocked(r, service.getFlags(), false)) { return new ComponentName("!", "Service process is bad"); } return r.name; } }ActivityManagerService在请求Zygote进程孵化新的应用程序进程时,在ActivityManagerService服务端为每一个应用程序进程创建了对应的ProcessRecord对象来描述新的应用程序进程信息,关于ActivityManagerService请求孵化新应用程序过程请参考 Android 应用进程启动过程的源码分析。函数首先根据应用程序进程中的IApplicationThread对象在最近启动的应用程序列表mLruProcesses中为服务启动进程查找对应的ProcessRecord对象,如果启动Service的应用程序进程还未启动,则抛出SecurityException异常。然后调用retrieveServiceLocked函数为当前启动的Service在ActivityManagerService服务端创建一个ServiceRecord对象来描述当前Service的信息。
frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
private ServiceLookupResult retrieveServiceLocked(Intent service, String resolvedType, int callingPid, int callingUid, int userId) { ServiceRecord r = null; if (DEBUG_SERVICE) Slog.v(TAG, "retrieveServiceLocked: " + service + " type=" + resolvedType + " callingUid=" + callingUid); //根据Service的包名从ActivityManagerService的成员变量mServiceMap中查找对应的ServiceRecord对象 if (service.getComponent() != null) { r = mServiceMap.getServiceByName(service.getComponent(), userId); } //根据启动Service的Intent信息从成员变量mServiceMap中查找对应的ServiceRecord对象 if (r == null) { Intent.FilterComparison filter = new Intent.FilterComparison(service); r = mServiceMap.getServiceByIntent(filter, userId); } //如果mServiceMap中不存在当前启动的Service对应的ServiceRecord对象 if (r == null) { try { //从PackageManager服务中获取当前启动Service的相关信息,并构造ResolveInfo对象 ResolveInfo rInfo =AppGlobals.getPackageManager().resolveService( service, resolvedType, STOCK_PM_FLAGS, userId); //获取Service信息对象 ServiceInfo sInfo = rInfo != null ? rInfo.serviceInfo : null; if (sInfo == null) { Slog.w(TAG, "Unable to start service " + service + ": not found"); return null; } if (userId > 0) { if (isSingleton(sInfo.processName, sInfo.applicationInfo)) { userId = 0; } sInfo.applicationInfo = getAppInfoForUser(sInfo.applicationInfo, userId); } ComponentName name = new ComponentName( sInfo.applicationInfo.packageName, sInfo.name); //再次根据Service的包名从成员变量mServiceMap中查找对应的ServiceRecord对象 r = mServiceMap.getServiceByName(name, userId); //依然查找不到 if (r == null) { Intent.FilterComparison filter = new Intent.FilterComparison( service.cloneFilter()); //为当前Service构造一个重启服务的Runnable对象 ServiceRestarter res = new ServiceRestarter(); BatteryStatsImpl.Uid.Pkg.Serv ss = null; BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); synchronized (stats) { ss = stats.getServiceStatsLocked( sInfo.applicationInfo.uid, sInfo.packageName, sInfo.name); } //为当前Service构造ServiceRecord对象 r = new ServiceRecord(this, ss, name, filter, sInfo, res); //设置ServiceRestarter重启的服务为当前Service res.setService(r); //将当前Service的服务端描述符ServiceRecord保存到mServiceMap中 mServiceMap.putServiceByName(name, UserId.getUserId(r.appInfo.uid), r); mServiceMap.putServiceByIntent(filter, UserId.getUserId(r.appInfo.uid), r); //通过服务名称查找mPendingServices服务列表中是否存在当前Service int N = mPendingServices.size(); for (int i=0; i<N; i++) { ServiceRecord pr = mPendingServices.get(i); if (pr.name.equals(name)) { mPendingServices.remove(i); i--; N--; } } } } catch (RemoteException ex) { // pm is in same process, this will never happen. } } if (r != null) { //检查服务权限 if (checkComponentPermission(r.permission, callingPid, callingUid, r.appInfo.uid, r.exported) != PackageManager.PERMISSION_GRANTED) { if (!r.exported) { Slog.w(TAG, "Permission Denial: Accessing service " + r.name + " from pid=" + callingPid + ", uid=" + callingUid + " that is not exported from uid " + r.appInfo.uid); return new ServiceLookupResult(null, "not exported from uid " + r.appInfo.uid); } Slog.w(TAG, "Permission Denial: Accessing service " + r.name + " from pid=" + callingPid + ", uid=" + callingUid + " requires " + r.permission); return new ServiceLookupResult(null, r.permission); } //返回ServiceLookupResult对象 return new ServiceLookupResult(r, null); } return null; }该函数通过一系列处理后,为当前启动的Service构造了对应的ServiceRecord对象,并保存到ActivityManagerService的成员变量mServiceMap中,这样就相当于在ActivityManagerService服务端完成了服务登记工作,接下来将调用bringUpServiceLocked函数正式启动这个已经记录在案的Service。
frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
private final boolean bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean whileRestarting) { //如果该Service服务已经创建,再次调用startService时,只调用该Service的onStartCommand来运行该Service if (r.app != null && r.app.thread != null) { //启动Service sendServiceArgsLocked(r, false); return true; } if (!whileRestarting && r.restartDelay > 0) { // If waiting for a restart, then do nothing. return true; } if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent); // 将当前启动的Service从服务重启列表mRestartingServices中移除 mRestartingServices.remove(r); // Service is now being launched, its package can't be stopped. try { AppGlobals.getPackageManager().setPackageStoppedState(r.packageName, false, r.userId); } catch (RemoteException e) { } catch (IllegalArgumentException e) { Slog.w(TAG, "Failed trying to unstop package "+ r.packageName + ": " + e); } //判断此Service是否在独立的进程中启动 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0; //得到在XML中设置该Service运行的进程名称 final String appName = r.processName; ProcessRecord app; //当前Service运行在应用程序进程,并非独立进程 if (!isolated) { //根据进程名称及UID从ActivityManagerService的成员变量mProcessNames中查找进程对应的描述符ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid); if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app); if (app != null && app.thread != null) { try { app.addPackage(r.appInfo.packageName); //在现有的进程中启动Service realStartServiceLocked(r, app); return true; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting service " + r.shortName, e); } } } else { // If this service runs in an isolated process, then each time // we call startProcessLocked() we will get a new isolated // process, starting another process if we are currently waiting // for a previous process to come up. To deal with this, we store // in the service any current isolated process it is running in or // waiting to have come up. app = r.isolatedProc; } // Not running -- get it started, and enqueue this service record // to be executed when the app comes up. if (app == null) { //启动应用程序进程 if ((app=startProcessLocked(appName, r.appInfo, true, intentFlags, "service", r.name, false, isolated)) == null) { Slog.w(TAG, "Unable to launch app " + r.appInfo.packageName + "/" + r.appInfo.uid + " for service " + r.intent.getIntent() + ": process is bad"); //强制退出Service bringDownServiceLocked(r, true); return false; } if (isolated) { r.isolatedProc = app; } } //当ActivityManagerService服务还为准备好时,mPendingServices用于保存客户进程请求启动的Servcie //保存当前请求启动的Service if (!mPendingServices.contains(r)) { mPendingServices.add(r); } return true; }如果当前系统中已经存在运行该Service的进程,则调用函数realStartServiceLocked来进一步启动Service,realStartServiceLocked函数的第一个参数是当前启动的Service在ActivityManagerService服务中的描述符对象ServiceRecord,第二个参数则是运行该Service的进程在ActivityManagerService服务中的描述符对象ProcessRecord,有了启动的Service和运行该Service的进程,接下来就可以真正启动该Service了。
frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
private final void realStartServiceLocked(ServiceRecord r,ProcessRecord app) throws RemoteException { if (app.thread == null) { throw new RemoteException(); } if (DEBUG_MU) Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid + ", ProcessRecord.uid = " + app.uid); // LC_RAM_SUPPORT if (LC_RAM_SUPPORT) { r.appAdj = ProcessRecord.TMP_CUR_ADJ_DEFAULT; r.hasFixAdj = (app.fixAdj != ProcessRecord.TMP_FIX_ADJ_DEFAULT); } r.app = app; r.restartTime = r.lastActivity = SystemClock.uptimeMillis(); //在ActivityManagerService服务中记录当前进程中运行的所有Service app.services.add(r); bumpServiceExecutingLocked(r, "create"); //mLruProcesses保存系统最近运行的应用程序进程信息,更新当前ProcessRecord在mLruProcesses变量中的状态 updateLruProcessLocked(app, true, true); boolean created = false; try { mStringBuilder.setLength(0); r.intent.getIntent().toShortString(mStringBuilder, true, false, true, false); EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE, System.identityHashCode(r), r.shortName, mStringBuilder.toString(), r.app.pid); synchronized (r.stats.getBatteryStats()) { r.stats.startLaunchedLocked(); } //检查当前Service所在包是否经过Dex优化过 ensurePackageDexOpt(r.serviceInfo.packageName); //创建Service服务 app.thread.scheduleCreateService(r, r.serviceInfo,compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo)); r.postNotification(); created = true; } finally { if (!created) { app.services.remove(r); scheduleServiceRestartLocked(r, false); } } //绑定该Service服务 requestServiceBindingsLocked(r); // If the service is in the started state, and there are no // pending arguments, then fake up one so its onStartCommand() will // be called. if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) { r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), null, null)); } //启动该Service服务 sendServiceArgsLocked(r, true); }在该函数中完成了Service的创建,Service的绑定,Service的启动。无论是Service的创建,绑定还是启动过程,都是由ActivityManagerService服务调度应用程序进程来完成的,通过Binder跨进程调用来实现。在此之前Service启动的前期工作都是在ActivityManagerService中完成,主要是实现Service的备案:
public final void scheduleCreateService(IBinder token, ServiceInfo info, CompatibilityInfo compatInfo) { CreateServiceData s = new CreateServiceData(); s.token = token;//ServiceRecord Binder本地对象 s.info = info; s.compatInfo = compatInfo; queueOrSendMessage(H.CREATE_SERVICE, s); }在ActivityThread类中定义了一个内部类H,继承于Handler,在Android应用程序进程启动过程中,我们介绍了Zygote进程通过复制一份自身进程地址空间来实现子进程的创建过程,孵化出来新的应用程序进程通过加载ActivityThread类,并调用该类的main函数为应用程序主线程建立消息循环,而定义的H这个Handler正是向主线程消息循环发送消息的通道,在这个函数中,将ActivityManagerService服务通过Binder跨进程调用Service运行进程的scheduleCreateService函数转换为本地的一个异步调用。在该函数中,将函数调用参数信息封装为CreateServiceData对象,然后通过queueOrSendMessage函数向应用程序主线程消息循环中发送一个CREATE_SERVICE消息,在H的handleMessage()函数中,完成对该消息的处理:
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"); handleCreateService((CreateServiceData)msg.obj); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; } }这里又将Service的创建工作交给H的外部类ActivityThread的handleCreateService()函数来完成。
private void handleCreateService(CreateServiceData data) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); //加载启动的Service类 LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo); Service service = null; try { java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = (Service) cl.loadClass(data.info.name).newInstance(); } catch (Exception e) { if (!mInstrumentation.onException(service, e)) { throw new RuntimeException( "Unable to instantiate service " + data.info.name + ": " + e.toString(), e); } } try { if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name); //为该Service创建一个上下文ContextImpl对象 ContextImpl context = new ContextImpl(); context.init(packageInfo, null, this); Application app = packageInfo.makeApplication(false, mInstrumentation); context.setOuterContext(service); //将Application,ActivityManagerService,当前Service在SystemServer进程中的ServiceRecord引用保存到当前Service的成员变量中 service.attach(context, this, data.info.name, data.token, app,ActivityManagerNative.getDefault()); //回调当前启动Service的onCreate函数 service.onCreate(); //变量mServices保存了应用程序进程中运行的所有Service mServices.put(data.token, service); //从应用程序进程进入SystemServer进程 try { //通知ActivityManagerService服务,当前Service创建完成 ActivityManagerNative.getDefault().serviceDoneExecuting(data.token, 0, 0, 0); } catch (RemoteException e) { // nothing to do. } } catch (Exception e) { if (!mInstrumentation.onException(service, e)) { throw new RuntimeException( "Unable to create service " + data.info.name + ": " + e.toString(), e); } } }在前面我们已经知道当前启动的Service在ActivityManagerService中已经记录在mServiceMap成员变量中了,对于运行Service的应用程序进程来说,仍然需要记录该进程中运行的Service信息,并保存在ActivityThread的成员变量mServices中。在该函数中加载启动Service的类,并为Service创建一个上下文对象,同时回调Service的onCreate()函数完成Service的创建过程。
private final void requestServiceBindingsLocked(ServiceRecord r) { //遍历当前Service的成员变量bindings Iterator<IntentBindRecord> bindings = r.bindings.values().iterator(); while (bindings.hasNext()) { IntentBindRecord i = bindings.next(); //调用requestServiceBindingLocked()函数绑定前Service if (!requestServiceBindingLocked(r, i, false)) { break; } } }ServiceRecord的成员变量bindings中保存了需要绑定当前Service的IntentBindRecord对象,在该函数中就是遍历bindings列表,然后调用requestServiceBindingLocked()函数来与当前Service绑定
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i, boolean rebind) { if (r.app == null || r.app.thread == null) { // If service is not currently running, can't yet bind. return false; } if ((!i.requested || rebind) && i.apps.size() > 0) { try { bumpServiceExecutingLocked(r, "bind"); //请求绑定服务 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind); if (!rebind) { i.requested = true; } i.hasBound = true; i.doRebind = false; } catch (RemoteException e) { if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r); return false; } } return true; }ActivityManagerService通过跨进程调用Service运行进程ApplicationThread的scheduleBindService函数来绑定服务
public final void scheduleBindService(IBinder token, Intent intent, boolean rebind) { BindServiceData s = new BindServiceData(); s.token = token; s.intent = intent; s.rebind = rebind; if (DEBUG_SERVICE) Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid=" + Binder.getCallingUid() + " pid=" + Binder.getCallingPid()); queueOrSendMessage(H.BIND_SERVICE, s); }将ActivityManagerService的RPC调用转换为本地异步调用
public void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); switch (msg.what) { case BIND_SERVICE: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind"); handleBindService((BindServiceData)msg.obj); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; } }
private void handleBindService(BindServiceData data) { //data.token为Service在AMS中的ServiceRecord Service s = mServices.get(data.token); if (DEBUG_SERVICE) Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind); if (s != null) { try { data.intent.setExtrasClassLoader(s.getClassLoader()); try { //是否重新绑定 if (!data.rebind) { //回调Service的onBind函数 IBinder binder = s.onBind(data.intent); //AMS回调ServiceConnection的connected函数 ActivityManagerNative.getDefault().publishService( data.token, data.intent, binder); } else { //回调Service的onRebind函数 s.onRebind(data.intent); ActivityManagerNative.getDefault().serviceDoneExecuting( data.token, 0, 0, 0); } ensureJitEnabled(); } catch (RemoteException ex) { } } catch (Exception e) { if (!mInstrumentation.onException(s, e)) { throw new RuntimeException( "Unable to bind to service " + s + " with " + data.intent + ": " + e.toString(), e); } } } }在该函数里,Service运行的应用程序进程调用Service的onBind函数。
public void publishService(IBinder token, Intent intent, IBinder service) { // Refuse possible leaked file descriptors if (intent != null && intent.hasFileDescriptors() == true) { throw new IllegalArgumentException("File descriptors passed in Intent"); } synchronized(this) { if (!(token instanceof ServiceRecord)) { throw new IllegalArgumentException("Invalid service token"); } ServiceRecord r = (ServiceRecord)token; final long origId = Binder.clearCallingIdentity(); if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r + " " + intent + ": " + service); if (r != null) { Intent.FilterComparison filter = new Intent.FilterComparison(intent); IntentBindRecord b = r.bindings.get(filter); if (b != null && !b.received) { b.binder = service; b.requested = true; b.received = true; if (r.connections.size() > 0) { Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator(); while (it.hasNext()) { ArrayList<ConnectionRecord> clist = it.next(); for (int i=0; i<clist.size(); i++) { ConnectionRecord c = clist.get(i); if (!filter.equals(c.binding.intent.intent)) { if (DEBUG_SERVICE) Slog.v( TAG, "Not publishing to: " + c); if (DEBUG_SERVICE) Slog.v( TAG, "Bound intent: " + c.binding.intent.intent); if (DEBUG_SERVICE) Slog.v( TAG, "Published intent: " + intent); continue; } if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c); try { c.conn.connected(r.name, service); } catch (Exception e) { Slog.w(TAG, "Failure sending service " + r.name + " to connection " + c.conn.asBinder() + " (in " + c.binding.client.processName + ")", e); } } } } } serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); Binder.restoreCallingIdentity(origId); } } }
private final void sendServiceArgsLocked(ServiceRecord r, boolean oomAdjusted) { final int N = r.pendingStarts.size(); if (N == 0) { return; } //遍历Service启动参数列表 while (r.pendingStarts.size() > 0) { try { //对参数列表中的每一项StartItem都启动一次Service ServiceRecord.StartItem si = r.pendingStarts.remove(0); if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: " + r + " " + r.intent + " args=" + si.intent); if (si.intent == null && N > 1) { // If somehow we got a dummy null intent in the middle, // then skip it. DO NOT skip a null intent when it is // the only one in the list -- this is to support the // onStartCommand(null) case. continue; } //设置投递时间 si.deliveredTime = SystemClock.uptimeMillis(); //将已投递参数项保存到deliveredStarts列表中 r.deliveredStarts.add(si); si.deliveryCount++; if (si.neededGrants != null) { grantUriPermissionUncheckedFromIntentLocked(si.neededGrants, si.getUriPermissionsLocked()); } bumpServiceExecutingLocked(r, "start"); if (!oomAdjusted) { oomAdjusted = true; updateOomAdjLocked(r.app); } int flags = 0; if (si.deliveryCount > 1) { flags |= Service.START_FLAG_RETRY; } if (si.doneExecutingCount > 0) { flags |= Service.START_FLAG_REDELIVERY; } //RPC调用Service运行进程的scheduleServiceArgs函数启动Service服务 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent); } catch (RemoteException e) { // Remote process gone... we'll let the normal cleanup take // care of this. if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r); break; } catch (Exception e) { Slog.w(TAG, "Unexpected exception", e); break; } } }和上面Service创建及绑定过程类似,这里仍然是通过Binder跨进程函数调用方式调用Service运行进程中的ApplicationThread Binder本地对象的scheduleServiceArgs()函数来启动Service
public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId, int flags ,Intent args) { ServiceArgsData s = new ServiceArgsData(); s.token = token; s.taskRemoved = taskRemoved; s.startId = startId; s.flags = flags; s.args = args; queueOrSendMessage(H.SERVICE_ARGS, s); }将RPC函数调用转换为应用程序进程中的异步调用
public void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); switch (msg.what) { case SERVICE_ARGS: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart"); handleServiceArgs((ServiceArgsData)msg.obj); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; } }该函数直接调用ActivityThread类的handleServiceArgs()函数来启动Service
private void handleServiceArgs(ServiceArgsData data) { Service s = mServices.get(data.token); if (s != null) { try { if (data.args != null) { data.args.setExtrasClassLoader(s.getClassLoader()); } int res; if (!data.taskRemoved) { //回调Service的onStartCommand函数 res = s.onStartCommand(data.args, data.flags, data.startId); } else { s.onTaskRemoved(data.args); res = Service.START_TASK_REMOVED_COMPLETE; } QueuedWork.waitToFinish(); try { //通知ActivityManagerService服务Service启动完成 ActivityManagerNative.getDefault().serviceDoneExecuting( data.token, 1, data.startId, res); } catch (RemoteException e) { // nothing to do. } ensureJitEnabled(); } catch (Exception e) { if (!mInstrumentation.onException(s, e)) { throw new RuntimeException( "Unable to start service " + s + " with " + data.args + ": " + e.toString(), e); } } } }
本文完整介绍了Service的创建启动过程,无论是Service的创建还是启动,Android应用程序进程自身都无法完成,必须通过ActivityManagerService服务调度实现,只有在ActivityManagerService服务端备案后,由ActivityManagerService服务通知应用程序进程来创建并启动Service。