ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
#### 9.3.1 Service的启动过程 Service的启动过程从ContextWrapper的startActivity开始,如下所示。 public ComponentName startService(Intent service) { return mBase.startService(service); } 上面代码的mBase的类型是ContextImpl,在9.2节中我们知道,Activity被创建时会通过attach方法将一个ContextImpl对象关联起来,这个ContextImpl对象就是上述代码中的mBase。从ContextWrapper的实现可以看出,其大部分操作都是通过mBase来实现的,在设计模式中这是一种典型的桥接模式。下面继续看ContextImpl的startActivity的实现,如下所示。 public ComponentName startService(Intent service) { warnIfCallingFromSystemProcess(); return startServiceCommon(service, mUser); } private ComponentName startServiceCommon(Intent service, UserHandle user) { try { validateServiceIntent(service); service.prepareToLeaveProcess(); ComponentName cn = ActivityManagerNative.getDefault().startService( mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver()), user.get- Identifier()); 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) { return null; } } 在ContextImpl中,startService方法会调用startServiceCommon方法,而startService-Common方法又会通过ActivityManagerNative.getDefault()这个对象来启动一个服务。对于ActivityManagerNative.getDefault()这个对象,我们应该有点印象,在9.2节中进行了详细的分析,它实际上就是AMS(ActivityManagerService),这里就不再重复说明了。需要注意的是,在上述代码中通过AMS来启动服务的行为是一个远程过程调用。AMS的startService方法的实现如下所示。 public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType, int userId) { enforceNotIsolatedCaller("startService"); // Refuse possible leaked file descriptors if (service ! = null && service.hasFileDescriptors() == true) { throw new IllegalArgumentException("File descriptors passed in Intent"); } if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service + " type=" + resolvedType); synchronized(this) { final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); ComponentName res = mServices.startServiceLocked(caller, service, resolvedType, callingPid, callingUid, userId); Binder.restoreCallingIdentity(origId); return res; } } 在上面的代码中,AMS会通过mServices这个对象来完成Service后续的启动过程,mServices对象的类型是ActiveServices, ActiveServices是一个辅助AMS进行Service管理的类,包括Service的启动、绑定和停止等。在ActiveServices的startServiceLocked方法的尾部会调用startServiceInnerLocked方法,startServiceInnerLocked的实现如下所示。 ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r, boolean callerFg, boolean addToStarting) { 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(); } 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 (DEBUG_DELAYED_SERVICE) { RuntimeException here = new RuntimeException("here"); here.fillInStackTrace(); Slog.v(TAG, "Starting background (first=" + first + "): " + r, here); } else if (DEBUG_DELAYED_STARTS) { Slog.v(TAG, "Starting background (first=" + first + "): " + r); } if (first) { smap.rescheduleDelayedStarts(); } } else if (callerFg) { smap.ensureNotStartingBackground(r); } return r.name; } 在上述代码中,ServiceRecord描述的是一个Service记录,ServiceRecord一直贯穿着整个Service的启动过程。startServiceInnerLocked方法并没有完成具体的启动工作,而是把后续的工作交给了bringUpServiceLocked方法来处理,在bringUpServiceLocked方法中又调用了realStartServiceLocked方法。从名字上来看,这个方法应该是真正地启动一个Service,它的实现如下所示。 private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { ... boolean created = false; try { String nameTerm; int lastPeriod = r.shortName.lastIndexOf('.'); nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName; if (LOG_SERVICE_START_STOP) { EventLogTags.writeAmCreateService( r.userId, System.identityHashCode(r), nameTerm, r.app. uid, r.app.pid); } synchronized (r.stats.getBatteryStats()) { r.stats.startLaunchedLocked(); } mAm.ensurePackageDexOpt(r.serviceInfo.packageName); app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE); app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo. applicationInfo), app.repProcState); r.postNotification(); created = true; } catch (DeadObjectException e) { Slog.w(TAG, "Application dead when creating service " + r); mAm.appDiedLocked(app); } finally { if (! created) { app.services.remove(r); r.app = null; scheduleServiceRestartLocked(r, false); return; } } requestServiceBindingsLocked(r, execInFg); updateServiceClientActivitiesLocked(app, null, true); // 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.make- NextStartId(), null, null)); } sendServiceArgsLocked(r, execInFg, true); ... } 在realStartServiceLocked方法中,首先通过app.thread的scheduleCreateService方法来创建Service对象并调用其onCreate,接着再通过sendServiceArgsLocked方法来调用Service的其他方法,比如onStartCommand,这两个过程均是进程间通信。app.thread对象是IApplicationThread类型,它实际上是一个Binder,它的具体实现是ApplicationThread和ApplicationThreadNative,在9.2节已经对这个问题做了说明。由于ApplicationThread继承了ApplicationThreadNative,因此只需要看ApplicationThread对Service启动过程的处理即可,这对应着它的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); } 很显然,这个过程和Activity的启动过程是类似的,都是通过发送消息给Handler H来完成的。H会接收这个CREATE_SERVICE消息并通过ActivityThread的handleCreateService方法来完成Service的最终启动,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(); 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); ContextImpl context = ContextImpl.createAppContext(this, packageInfo); context.setOuterContext(service); Application app = packageInfo.makeApplication(false, mInstrumen- tation); service.attach(context, this, data.info.name, data.token, app, ActivityManagerNative.getDefault()); service.onCreate(); mServices.put(data.token, service); try { 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); } } } handleCreateService主要完成了如下几件事。 首先通过类加载器创建Service的实例。 然后创建Application对象并调用其onCreate,当然Application的创建过程只会有一次。 接着创建ConTextImpl对象并通过Service的attach方法建立二者之间的关系,这个过程和Activity实际上是类似的,毕竟Service和Activity都是一个Context。 最后调用Service的onCreate方法并将Service对象存储到ActivityThread中的一个列表中。这个列表的定义如下所示。 final ArrayMap<IBinder, Service> mServices = new ArrayMap<IBinder, Service>() 由于Service的onCreate方法被执行了,这也意味着Service已经启动了。除此之外,ActivityThread中还会通过handleServiceArgs方法调用Service的onStartCommand方法,如下所示。 private void handleServiceArgs(ServiceArgsData data) { Service s = mServices.get(data.token); if (s ! = null) { try { if (data.args ! = null) { data.args.setExtrasClassLoader(s.getClassLoader()); data.args.prepareToEnterProcess(); } int res; if (! data.taskRemoved) { res = s.onStartCommand(data.args, data.flags, data.startId); } else { s.onTaskRemoved(data.args); res = Service.START_TASK_REMOVED_COMPLETE; } QueuedWork.waitToFinish(); try { 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的绑定过程。