目录
前言
startService()源码分析之前Android 6.0是有简单分析过的,但太久了,而且记录也很粗糙,到现在也忘记得差不多了。
最近抽空重新走一下,也算是自己的复习吧。
这里看的是Android P的源代码。
正文
这里是Apk1去启动Apk2的服务(Apk2没有启动过)
Intent intent = new Intent(); intent.setPackage("com.biumall.server"); intent.setComponent(new ComponentName("com.biumall.server", "com.biumall.server.DemoService")); startService(intent);
PS: Apk1和Apk2都为系统应用,要不然:
Not allowed to start service Intent { xxxxx }: app is in background uid null
因为Apk2没有启动。系统应用区启动就没啥问题。这部分可以看《》
回归正题。进入源码分析。
ContextImpl.java才是Context背后的大佬,这里直接进入。
ContextImpl.java
startService()
@Override public ComponentName startService(Intent service) { return startServiceCommon(service, false, mUser); }
startServiceCommon()
private ComponentName startServiceCommon(Intent service, boolean requireForeground, UserHandle user) { try { //略 [不是分析重点都会略去] //ActivityManager.getService()是ActivityManagerService //这部分的分析网上很多,之前也跟过,但没单独分开,后续有机会单独写一下 //这里调用的是ActivityManagerService.startService() ComponentName cn = ActivityManager.getService().startService( mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded( getContentResolver()), requireForeground, getOpPackageName(), user.getIdentifier()); //略 return cn; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }
关于ActivityManager.getService()的,如果不懂就百度吧,我之前文件有解释过。
也就是启动服务最终还是进入ActivityManagerService中。
ActivityManagerService.java
startService()
@Override 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 { //调用ActiveServices.startServiceLocked() res = mServices.startServiceLocked(caller, service, resolvedType, callingPid, callingUid, requireForeground, callingPackage, userId); } finally { Binder.restoreCallingIdentity(origId); } return res; } }
ActiveServices.java
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)throws TransactionTooLargeException { //略 //这里很多初始化和判断,但不关心,跳过,如果需要就看源码 //调用的是startServiceInnerLocked() ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting); return cmp; }
startServiceInnerLocked()
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r, boolean callerFg, boolean addToStarting) throws TransactionTooLargeException { ServiceState stracker = r.getTracker(); //stracker为null,我们还没启动过呢 if (stracker != null) { stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity); } //略 //重点,这里是拉起服务 String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false); //进程启动成功 ,error为null if (error != null) { return new ComponentName("!!", error); } //略 return r.name; }
bringUpServiceLocked()
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting, boolean permissionsReviewRequired) throws TransactionTooLargeException { //[重1]r.app是不为null,也即是进程存在,可以直接启动服务 if (r.app != null && r.app.thread != null) { //如果满足上面条件,ApplicationInfo信息存在 sendServiceArgsLocked(r, execInFg, false); return null; } //还没启动,不包含 if (!whileRestarting && mRestartingServices.contains(r)) { return null; } //还没启动,不包含 if (mRestartingServices.remove(r)) { clearRestartingIfNeededLocked(r); } //不需要延迟,至于是否需要延迟,看前面的赋值条件 if (r.delayed) { getServiceMapLocked(r.userId).mDelayedStartList.remove(r); r.delayed = false; } if (!mAm.mUserController.hasStartedUserState(r.userId)) { bringDownServiceLocked(r); return msg; } try { AppGlobals.getPackageManager().setPackageStoppedState( r.packageName, false, r.userId); } catch (RemoteException e) { //略 } final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0; final String procName = r.processName; String hostingType = "service"; ProcessRecord app; //判读是否是独立进程false if (!isolated) { //[重2]获取ProcessRecord,通过ActivityManagerService获取,进程信息 //如果这里能获取到ProcessRecord,表示进程也是启动过的,这里就启动服务。 app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false); //没有启动过,app= null if (app != null && app.thread != null) { try { app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats); //启动服务 realStartServiceLocked(r, app, execInFg); return null; } catch (TransactionTooLargeException e) { throw e; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting service " + r.shortName, e); } } } else { //略 } //进程没有启动,这里启动进程 //传入的permissionsReviewRequired为false if (app == null && !permissionsReviewRequired) { //[重3]这里进行启动进程 if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags, hostingType, r.name, false, isolated, false)) == null) { //启动失败才走这里。 bringDownServiceLocked(r); return msg; } //略 } //略 //[重4],这里添加服务到Pending列表 if (!mPendingServices.contains(r)) { mPendingServices.add(r); } //略 return null; }
重点。分为如下几个步骤。
-
[重1]判断ServiceRecord中是否带有ApplicationInfo信息,如果有,表示Application已经启动了,调用sendServiceArgsLocked。
-
[重2]查看是否有ProcessRecord信息,如果有直接进入realStartServiceLocked()
-
[重3]进程启动,上面两个条件不满足,表示进程不存在,需要fork一个进程来。
-
[重4]把服务添加到mPendingServices中,等进程启动完层后启动。
由于我们进程没有启动过,因此,需要等进程启动成功后才可以启动服务。因此,startService()大部分执行完成。
接下来就是等待进程的启动,然后系统把Service拉起来。
下面关注进程的启动。
ActivityManagerService.java
startProcessLocked()
@GuardedBy("this") final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, boolean allowWhileBooting, boolean isolated, boolean keepIfLarge) { return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, null /* crashHandler */); }
由于进程的启动这部分跟《》重合,也就是Zygote会fork出一个子进程,然后通过反射启动ActivityThread.java的main()方法。
进程启动略
想看的直接看《》吧。
ActivityThread.java
这部分跟《》也跟重复,因此,下面也就大概的走一下。
main()
public static void main(String[] args) { //略 Looper.prepareMainLooper(); long startSeq = 0; //创建一个ActivityThread ActivityThread thread = new ActivityThread(); //[重]这里执行了attach() thread.attach(false, startSeq); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } //进入循环,正常情况不会退出的 Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
attach()
private void attach(boolean system, long startSeq) { //略 //传入的system为false if (!system) { //略 //获取的是ActivityManagerService final IActivityManager mgr = ActivityManager.getService(); try { //[重]进行attach mgr.attachApplication(mAppThread, startSeq); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } //略 } //略 }
ActivityManagerService.java
attachApplication()
@Override public final void attachApplication(IApplicationThread thread, long startSeq) { synchronized (this) { //略 attachApplicationLocked(thread, callingPid, callingUid, startSeq); //略 } }
attachApplicationLocked()
@GuardedBy("this") private final boolean attachApplicationLocked(IApplicationThread thread, int pid, int callingUid, long startSeq) { //略 final String processName = app.processName; try { AppDeathRecipient adr = new AppDeathRecipient(app, pid, thread); //binder死亡监听 thread.asBinder().linkToDeath(adr, 0); app.deathRecipient = adr; } catch (RemoteException e) { app.resetPackageList(mProcessStats); startProcessLocked(app, "link fail", processName); return false; } //略 try { //略 //isolatedEntryPoint为null if (app.isolatedEntryPoint != null) { thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs); } else if (app.instr != null) { //略 } else { //[重1]绑定bindApplication //通过Handler处理,主要是执行Application的onCreate()方法。 //这里不会阻塞!!! thread.bindApplication(processName, appInfo, providers, null, profilerInfo, null, null, null, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(getGlobalConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, isAutofillCompatEnabled); } //略 } catch (Exception e) { //略 return false; } //略 boolean badApp = false; boolean didSomething = false; //启动Activity if (normalMode) { try { //重点启动Activity相关 if (mStackSupervisor.attachApplicationLocked(app)) { didSomething = true; } } catch (Exception e) { badApp = true; } } //启动服务 if (!badApp) { try { //[重2],启动服务 didSomething |= mServices.attachApplicationLocked(app, processName); checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked"); } catch (Exception e) { badApp = true; } } //启动广播 if (!badApp && isPendingBroadcastProcessLocked(pid)) { try { //重点 didSomething |= sendPendingBroadcastsLocked(app); } catch (Exception e) { badApp = true; } } //略 return true; }
这个方法比较重要,涉及如下几个内容
-
Application的启动,执行onCreate()
-
Activity的启动,执行onCreate(),看是否有满足条件的。
-
Service的启动,执行onCreate(),看是否有满足条件的。
-
发送广播 (不过,这部分我没跟,看代码是有,暂时保留吧,后续跟踪)
我们这里只关心Service的启动,至于[重1]Application的onCreate()启动,麻烦移步到《》。
好的,我们看[重2]那部分代码。
if (!badApp) { try { didSomething |= mServices.attachApplicationLocked(app, processName); } catch (Exception e) { badApp = true; } }
ActiveServices.java
attachApplicationLocked()
boolean attachApplicationLocked(ProcessRecord proc, String processName) throws RemoteException { boolean didSomething = false; //Pending中的服务,这里大于0 if (mPendingServices.size() > 0) { ServiceRecord sr = null; try { for (int i=0; i<mPendingServices.size(); i++) { sr = mPendingServices.get(i); //sr就是上面保存的Service信息 //ServiceRecord{66fcbc0 u0 com.biumall.biuaidlserver/.server.DemoService} if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid || !processName.equals(sr.processName))) { continue; } //找到了,先移除mPendingServices mPendingServices.remove(i); i--; proc.addPackage(sr.appInfo.packageName, sr.appInfo.longVersionCode, mAm.mProcessStats); //[重]启动服务,看包名就知道啥意思哈 realStartServiceLocked(sr, proc, sr.createdFromFg); didSomething = true; if (!isServiceNeededLocked(sr, false, false)) { bringDownServiceLocked(sr); } } } catch (RemoteException e) { throw e; } } //重新启动的服务为0 if (mRestartingServices.size() > 0) { //略 } return didSomething; }
realStartServiceLocked()
private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { //thread不为null的 if (app.thread == null) { throw new RemoteException(); } r.app = app; r.restartTime = r.lastActivity = SystemClock.uptimeMillis(); final boolean newService = app.services.add(r); //发送SERVICE_TIMEOUT_MSG,超时就ANR //前台服务20s超时会ANR //后台服务超时200s超时会ANR bumpServiceExecutingLocked(r, execInFg, "create"); mAm.updateLruProcessLocked(app, false, null); updateServiceForegroundLocked(r.app, /* oomAdj= */ false); mAm.updateOomAdjLocked(); //判断服务是否创建 boolean created = false; try { //略 mAm.notifyPackageUse(r.serviceInfo.packageName, PackageManager.NOTIFY_PACKAGE_USE_SERVICE); app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE); //[重]创建服务的启动 //ActivityThread.scheduleCreateService app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), app.repProcState); r.postNotification(); created = true; } catch (DeadObjectException e) { mAm.appDiedLocked(app); throw e; } finally { //没有异常的话,为true,异常的话重新启动服务。 if (!created) { // Keep the executeNesting count accurate. final boolean inDestroying = mDestroyingServices.contains(r); serviceDoneExecutingLocked(r, inDestroying, inDestroying); // Cleanup. if (newService) { app.services.remove(r); r.app = null; } // Retry. if (!inDestroying) { scheduleServiceRestartLocked(r, false); } } } //略 //[重]会发送sendServiceArgsLocked sendServiceArgsLocked(r, execInFg, true); //不是延迟启动的,如果到此已经启动差不多了,需要从列表中移除 if (r.delayed) { getServiceMapLocked(r.userId).mDelayedStartList.remove(r); r.delayed = false; } //略 }
我们主要关注下面两个方法。
-
scheduleCreateService()
-
sendServiceArgsLocked()
先看scheduleCreateService()
ActivityThread.java
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; //发送CREATE_SERVICE sendMessage(H.CREATE_SERVICE, s); }
handleMessage()
case CREATE_SERVICE: //处理创建服务 handleCreateService((CreateServiceData)msg.obj);1 break; case BIND_SERVICE:
handleCreateService()
private void handleCreateService(CreateServiceData data) { unscheduleGcIdler(); LoadedApk packageInfo = getPackageInfoNoCheck( data.info.applicationInfo, data.compatInfo); Service service = null; try { java.lang.ClassLoader cl = packageInfo.getClassLoader(); //发射,new一个Service //这里不跟,具体看instantiateService service = packageInfo.getAppFactory() .instantiateService(cl, data.info.name, data.intent); } catch (Exception e) { if (!mInstrumentation.onException(service, e)) { throw new RuntimeException( "Unable to instantiate service " + data.info.name + ": " + e.toString(), e); } } try { //创建Service的Context ContextImpl context = ContextImpl.createAppContext(this, packageInfo); context.setOuterContext(service); //创建Application //Application上面已经创建了,这里只是获取创建的 //跟Activity的分析一样。 Application app = packageInfo.makeApplication(false, mInstrumentation); //service 绑定context service.attach(context, this, data.info.name, data.token, app, ActivityManager.getService()); //调用Service的onCreate() service.onCreate(); mServices.put(data.token, service); //略 } catch (Exception e) { if (!mInstrumentation.onException(service, e)) { throw new RuntimeException( "Unable to create service " + data.info.name + ": " + e.toString(), e); } } }
创建Context,调用了服务的onCreate()。
Service.java
此时的Service是com.biumall.server.DemoService
DemoService.onCreate()
public void onCreate() { }
至此,我们的服务依旧执行了onCreate(),也算是启动完成了。
接着继续分析ActiveServices.java的realStartServiceLocked()中sendServiceArgsLocked()
ActiveServices.java
sendServiceArgsLocked()
private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg, boolean oomAdjusted) throws TransactionTooLargeException { //pendingStarts在startServiceLocked()添加的。 final int N = r.pendingStarts.size(); //不为0 if (N == 0) { return; } //略 try { //[重]scheduleServiceArgs,有回到了ActivityThread r.app.thread.scheduleServiceArgs(r, slice); } catch (TransactionTooLargeException e) { caughtException = e; } catch (RemoteException e) { caughtException = e; } catch (Exception e) { caughtException = e; } //略 }
ActivityThread.java
scheduleServiceArgs()
public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) { List<ServiceStartArgs> list = args.getList(); for (int i = 0; i < list.size(); i++) { ServiceStartArgs ssa = list.get(i); ServiceArgsData s = new ServiceArgsData(); s.token = token; s.taskRemoved = ssa.taskRemoved; s.startId = ssa.startId; s.flags = ssa.flags; s.args = ssa.args; //发送SERVICE_ARGS sendMessage(H.SERVICE_ARGS, s); } }
handleMessage()
case SERVICE_ARGS: handleServiceArgs((ServiceArgsData)msg.obj); break;
handleServiceArgs()
private void handleServiceArgs(ServiceArgsData data) { Service s = mServices.get(data.token); if (s != null) { try { //略 //data.taskRemoved为false if (!data.taskRemoved) { //[重]这里执行了onStartCommand res = s.onStartCommand(data.args, data.flags, data.startId); } else { s.onTaskRemoved(data.args); res = Service.START_TASK_REMOVED_COMPLETE; } QueuedWork.waitToFinish(); try { ActivityManager.getService().serviceDoneExecuting( data.token, SERVICE_DONE_EXECUTING_START, data.startId, res); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } ensureJitEnabled(); } catch (Exception e) { if (!mInstrumentation.onException(s, e)) { throw new RuntimeException( "Unable to start service " + s + " with " + data.args + ": " + e.toString(), e); } } } }
哈哈,是不是意外,这里执行了onStartCommand()
Service.java
此时的Service是com.biumall.server.DemoService
DemoService.onStartCommand()
public @StartResult int onStartCommand(Intent intent, @StartArgFlags int flags, int startId) { onStart(intent, startId); return mStartCompatibility ? START_STICKY_COMPATIBILITY : START_STICKY; }
到此,服务就启动完成了。
参考文章
部分内容涉及这里,其实很堵都类似的。
-
《》
-
《》
老文章,感觉也是摘抄的吧,忘了。
-
《》
-
《》
-
《》