//试图用一个不存在的用户启动Service if (!mAm.mUserController.exists(r.userId)) { Slog.w(TAG, "Trying to start service with non-existent user! " + r.userId); returnnull; }
// If we're starting indirectly (e.g. from PendingIntent), figure out whether // we're launching into an app in a background state. This keys off of the same // idleness state tracking as e.g. O+ background service start policy. //Service所在应用未启动或处在后台 finalboolean bgLaunch = !mAm.isUidActiveLocked(r.appInfo.uid);
// If the app has strict background restrictions, we treat any bg service // start analogously to the legacy-app forced-restrictions case, regardless // of its target SDK version. //检查Service所在应用后台启动限制 boolean forcedStandby = false; if (bgLaunch && appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) { forcedStandby = true; }
// If this is a direct-to-foreground start, make sure it is allowed as per the app op. boolean forceSilentAbort = false; if (fgRequired) { //作为前台服务启动 //权限检查 finalint mode = mAm.getAppOpsManager().checkOpNoThrow( AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName); switch (mode) { //默认和允许都可以作为前台服务启动 case AppOpsManager.MODE_ALLOWED: case AppOpsManager.MODE_DEFAULT: // All okay. break; //不允许的话,回退到作为普通后台服务启动 case AppOpsManager.MODE_IGNORED: // Not allowed, fall back to normal start service, failing siliently // if background check restricts that. Slog.w(TAG, "startForegroundService not allowed due to app op: service " + service + " to " + r.shortInstanceName + " from pid=" + callingPid + " uid=" + callingUid + " pkg=" + callingPackage); fgRequired = false; forceSilentAbort = true; break; //错误的话直接返回,由上层抛出SecurityException异常 default: returnnew ComponentName("!!", "foreground not allowed as per app op"); } }
// If this isn't a direct-to-foreground start, check our ability to kick off an // arbitrary service //如果不是从前台启动 //startRequested表示Service是否由startService方式所启动,fgRequired表示作为前台服务启动 if (forcedStandby || (!r.startRequested && !fgRequired)) { // Before going further -- if this app is not allowed to start services in the // background, then at this point we aren't going to let it period. //服务是否允许在后台启动 finalint allowed = mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName, r.appInfo.targetSdkVersion, callingPid, false, false, forcedStandby); //如果不允许,则无法启动服务 if (allowed != ActivityManager.APP_START_MODE_NORMAL) { //静默的停止启动 if (allowed == ActivityManager.APP_START_MODE_DELAYED || forceSilentAbort) { // In this case we are silently disabling the app, to disrupt as // little as possible existing apps. returnnull; } if (forcedStandby) { // This is an O+ app, but we might be here because the user has placed // it under strict background restrictions. Don't punish the app if it's // trying to do the right thing but we're denying it for that reason. if (fgRequired) { returnnull; } } // This app knows it is in the new model where this operation is not // allowed, so tell it what has happened. //明确的告知不允许启动,上层抛出异常 UidRecord uidRec = mAm.mProcessList.getUidRecordLocked(r.appInfo.uid); returnnew ComponentName("?", "app is in background uid " + uidRec); } }
// At this point we've applied allowed-to-start policy based on whether this was // an ordinary startService() or a startForegroundService(). Now, only require that // the app follow through on the startForegroundService() -> startForeground() // contract if it actually targets O+. //对于targetSdk 26以下(Android 8.0以下)的应用来说,不需要作为前台服务启动 if (r.appInfo.targetSdkVersion < Build.VERSION_CODES.O && fgRequired) { fgRequired = false; }
// If permissions need a review before any of the app components can run, // we do not start the service and launch a review activity if the calling app // is in the foreground passing it a pending intent to start the service when // review is completed.
// XXX This is not dealing with fgRequired! //如果待启动的Service需要相应权限,则需要用户手动确认权限后,再进行启动 if (!requestStartTargetPermissionsReviewIfNeededLocked(r, callingPackage, callingFeatureId, callingUid, service, callerFg, userId)) { returnnull; }
//取消之前的Service重启任务(如果有) if (unscheduleServiceRestartLocked(r, callingUid, false)) { if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "START SERVICE WHILE RESTART PENDING: " + r); } r.lastActivity = SystemClock.uptimeMillis(); //表示Service是否由startService方式所启动的 r.startRequested = true; r.delayedStop = false; //是否作为前台服务启动 r.fgRequired = fgRequired; //构造启动参数 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), service, neededGrants, callingUid));
//作为前台服务启动 if (fgRequired) { // We are now effectively running a foreground service. ... //使用ServiceState记录 ... //通过AppOpsService监控 }
final ServiceMap smap = getServiceMapLocked(r.userId); boolean addToStarting = false; //对于后台启动的非前台服务,需要判断其是否需要延迟启动 if (!callerFg && !fgRequired && r.app == null && mAm.mUserController.hasStartedUserState(r.userId)) { //获取Service所处进程信息 ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false); //没有对应进程或进程状态级别低于 [进程在后台运行Receiver] if (proc == null || proc.getCurProcState() > ActivityManager.PROCESS_STATE_RECEIVER) { // If this is not coming from a foreground caller, then we may want // to delay the start if there are already other background services // that are starting. This is to avoid process start spam when lots // of applications are all handling things like connectivity broadcasts. // We only do this for cached processes, because otherwise an application // can have assumptions about calling startService() for a service to run // in its own process, and for that process to not be killed before the // service is started. This is especially the case for receivers, which // may start a service in onReceive() to do some additional work and have // initialized some global state as part of that. //对于之前已经设置为延迟启动的服务,直接返回 if (r.delayed) { // This service is already scheduled for a delayed start; just leave // it still waiting. return r.name; } //如果当前正在后台启动的Service数大于等于允许同时在后台启动的最大服务数 //将这个Service设置为延迟启动 if (smap.mStartingBackground.size() >= mMaxStartingBackground) { // Something else is starting, delay! smap.mDelayedStartList.add(r); r.delayed = true; return r.name; } //添加到正在启动服务列表中 addToStarting = true; } elseif (proc.getCurProcState() >= ActivityManager.PROCESS_STATE_SERVICE) { //进程状态为 [正在运行Service的后台进程] 或 [正在运行Receiver的后台进程] 时 // We slightly loosen when we will enqueue this new service as a background // starting service we are waiting for, to also include processes that are // currently running other services or receivers. //添加到正在启动服务列表中 addToStarting = true; } }
//如果服务正在重启中,则什么都不做,直接返回 if (!whileRestarting && mRestartingServices.contains(r)) { // If waiting for a restart, then do nothing. returnnull; }
// We are now bringing the service up, so no longer in the // restarting state. //Service马上启动,将其从重启中服务列表中移除,并清除其重启中状态 if (mRestartingServices.remove(r)) { clearRestartingIfNeededLocked(r); }
// Make sure this service is no longer considered delayed, we are starting it now. //走到这里,需要确保此服务不再被视为延迟启动,同时将其从延迟启动服务列表中移除 if (r.delayed) { getServiceMapLocked(r.userId).mDelayedStartList.remove(r); r.delayed = false; }
// Make sure that the user who owns this service is started. If not, // we don't want to allow it to run. //确保Service所在的用户已启动 if (!mAm.mUserController.hasStartedUserState(r.userId)) { //停止服务 bringDownServiceLocked(r); return msg; }
// Service is now being launched, its package can't be stopped. //Service即将启动,Service所属的App不该为stopped状态 //将App状态置为unstopped,设置休眠状态为false AppGlobals.getPackageManager().setPackageStoppedState( r.packageName, false, r.userId);
//服务所在进程是否为隔离进程,指服务是否在其自己的独立进程中运行 finalboolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0; final String procName = r.processName; HostingRecord hostingRecord = new HostingRecord("service", r.instanceName); ProcessRecord app;
// If a dead object exception was thrown -- fall through to // restart the application. } } 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; //辅助zygote进程,用于创建isolated_app进程来渲染不可信的web内容,具有最为严格的安全限制 if (WebViewZygote.isMultiprocessEnabled() && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) { hostingRecord = HostingRecord.byWebviewZygote(r.instanceName); } //应用zygote进程,与常规zygote创建的应用相比受到更多限制 if ((r.serviceInfo.flags & ServiceInfo.FLAG_USE_APP_ZYGOTE) != 0) { hostingRecord = HostingRecord.byAppZygote(r.instanceName, r.definingPackageName, r.definingUid); } }
// Not running -- get it started, and enqueue this service record // to be executed when the app comes up. //如果Service所在进程尚未启动 if (app == null && !permissionsReviewRequired) { // TODO (chriswailes): Change the Zygote policy flags based on if the launch-for-service // was initiated from a notification tap or not. //启动App进程 if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags, hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false, isolated, false)) == null) { //如果启动进程失败,停止服务 bringDownServiceLocked(r); return msg; } if (isolated) { //如果是隔离进程,将这次启动的进程记录保存下来 r.isolatedProc = app; } }
//对于要启动的前台服务,加入到临时白名单,暂时绕过省电模式 if (r.fgRequired) { mAm.tempWhitelistUidLocked(r.appInfo.uid, SERVICE_START_FOREGROUND_TIMEOUT, "fg-service-launch"); }
//将启动的服务添加到mPendingServices列表中 //如果服务进程尚未启动,进程在启动的过程中会检查此列表并启动需要启动的Service if (!mPendingServices.contains(r)) { mPendingServices.add(r); }
//Service被要求stop,停止服务 if (r.delayedStop) { // Oh and hey we've already been asked to stop! r.delayedStop = false; if (r.startRequested) { stopServiceLocked(r); } }
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java privatebooleanattachApplicationLocked(@NonNull IApplicationThread thread, int pid, int callingUid, long startSeq){ ... // Find any services that should be running in this process... //检查是否有Services等待启动 if (!badApp) { try { didSomething |= mServices.attachApplicationLocked(app, processName); } catch (Exception e) { badApp = true; } } ... }
// Update the app background restriction of the caller //更新Service所在App后台限制 proc.mState.setBackgroundRestricted(appRestrictedAnyInBackground( proc.uid, proc.info.packageName));
// Collect any services that are waiting for this process to come up. //启动mPendingServices列表内,该进程下的所有Service if (mPendingServices.size() > 0) { ServiceRecord sr = null; try { for (int i=0; i<mPendingServices.size(); i++) { sr = mPendingServices.get(i); if (proc != sr.isolationHostProc && (proc.uid != sr.appInfo.uid || !processName.equals(sr.processName))) { continue; }
final IApplicationThread thread = proc.getThread(); finalint pid = proc.getPid(); final UidRecord uidRecord = proc.getUidRecord(); mPendingServices.remove(i); i--; //将App添加至进程中运行的包列表中 proc.addPackage(sr.appInfo.packageName, sr.appInfo.longVersionCode, mAm.mProcessStats); //启动Service realStartServiceLocked(sr, proc, thread, pid, uidRecord, sr.createdFromFg, true); didSomething = true; //如果此Service不再需要了,则停止它 //e.g. 通过bindService启动的服务,但此时调用bindService的Activity已死亡 if (!isServiceNeededLocked(sr, false, false)) { // We were waiting for this service to start, but it is actually no // longer needed. This could happen because bringDownServiceIfNeeded // won't bring down a service that is pending... so now the pending // is done, so let's drop it. bringDownServiceLocked(sr, true); } /* Will be a no-op if nothing pending */ //更新进程优先级 mAm.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_START_SERVICE); } } catch (RemoteException e) { throw e; } } // Also, if there are any services that are waiting to restart and // would run in this process, now is a good time to start them. It would // be weird to bring up the process but arbitrarily not let the services // run at this point just because their restart time hasn't come up. //App被杀重启机制,后续文章再详细说明 if (mRestartingServices.size() > 0) { ... } return didSomething; }
//frameworks/base/services/core/java/com/android/server/am/ActiveServices.java /** * Note the name of this method should not be confused with the started services concept. * The "start" here means bring up the instance in the client, and this method is called * from bindService() as well. */ privatefinalvoidrealStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg)throws RemoteException { //IApplicationThread不存在则抛移除 //即确保ActivityThread存在 if (app.thread == null) { thrownew RemoteException(); } //为ServiceRecord设置所属进程 r.setProcess(app); r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
//添加绑定到Service所在进程的UID if (newService && created) { app.addBoundClientUidsOfNewService(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. //如果Service已经启动,并且没有启动项,则构建一个假的启动参数供onStartCommand使用 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) { r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), null, null, 0)); }
//走到这里,需要确保此服务不再被视为延迟启动,同时将其从延迟启动服务列表中移除 if (r.delayed) { getServiceMapLocked(r.userId).mDelayedStartList.remove(r); r.delayed = false; }
//Service被要求stop,停止服务 if (r.delayedStop) { // Oh and hey we've already been asked to stop! r.delayedStop = false; if (r.startRequested) { stopServiceLocked(r); } } }
//frameworks/base/core/java/android/app/ActivityThread.java privatevoidhandleCreateService(CreateServiceData data){ // If we are getting ready to gc after going to the background, well // we are back active so skip it. //此时不要进行GC unscheduleGcIdler();
LoadedApk packageInfo = getPackageInfoNoCheck( data.info.applicationInfo, data.compatInfo); Service service = null; try { //创建Context ContextImpl context = ContextImpl.createAppContext(this, packageInfo); //创建或获取Application(到了这里进程的初始化应该都完成了,所以是直接获取Application) Application app = packageInfo.makeApplication(false, mInstrumentation); java.lang.ClassLoader cl = packageInfo.getClassLoader(); //通过AppComponentFactory反射创建Service实例 service = packageInfo.getAppFactory() .instantiateService(cl, data.info.name, data.intent); // Service resources must be initialized with the same loaders as the application // context. //加载资源 context.getResources().addLoaders( app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
ArrayList<ServiceStartArgs> args = new ArrayList<>();
//遍历待启动项 while (r.pendingStarts.size() > 0) { ServiceRecord.StartItem si = r.pendingStarts.remove(0); //如果在多个启动项中有假启动项,则跳过假启动项 //但如果这个假启动项是唯一的启动项则不要跳过它,这是为了支持onStartCommand(null)的情况 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(); r.deliveredStarts.add(si); si.deliveryCount++; //处理Uri权限 if (si.neededGrants != null) { mAm.mUgmInternal.grantUriPermissionUncheckedFromIntent(si.neededGrants, si.getUriPermissionsLocked()); } //授权访问权限 mAm.grantImplicitAccess(r.userId, si.intent, si.callingId, UserHandle.getAppId(r.appInfo.uid) ); //记录Service执行操作并设置超时回调 //前台服务超时时间为20s,后台服务超时时间为200s bumpServiceExecutingLocked(r, execInFg, "start"); if (!oomAdjusted) { oomAdjusted = true; mAm.updateOomAdjLocked(r.app, true, OomAdjuster.OOM_ADJ_REASON_START_SERVICE); } //如果是以前台服务的方式启动的Service(startForegroundService),并且之前没有设置启动前台服务超时回调 if (r.fgRequired && !r.fgWaiting) { //如果当前服务还没成为前台服务,设置启动前台服务超时回调 //在10s内需要调用Service.startForeground成为前台服务,否则停止服务 //注:Android 11这个超时时间是10s,在后面的Android版本中这个时间有变化 if (!r.isForeground) { scheduleServiceForegroundTransitionTimeoutLocked(r); } else { r.fgRequired = false; } } int flags = 0; if (si.deliveryCount > 1) { flags |= Service.START_FLAG_RETRY; } if (si.doneExecutingCount > 0) { flags |= Service.START_FLAG_REDELIVERY; } //添加启动项 args.add(new ServiceStartArgs(si.taskRemoved, si.id, flags, si.intent)); }
//frameworks/base/core/java/android/app/ActivityThread.java privatevoidhandleServiceArgs(ServiceArgsData data){ Service s = mServices.get(data.token); if (s != null) { try { //Intent跨进程处理 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 { //用户关闭Task栈时调用 s.onTaskRemoved(data.args); res = Service.START_TASK_REMOVED_COMPLETE; }
// Refuse possible leaked file descriptors //校验Intent,不允许其携带fd if (service != null && service.hasFileDescriptors() == true) { thrownew IllegalArgumentException("File descriptors passed in Intent"); }
//校验调用方包名 if (callingPackage == null) { thrownew IllegalArgumentException("callingPackage cannot be null"); }
// Ensure that instanceName, which is caller provided, does not contain // unusual characters. if (instanceName != null) { for (int i = 0; i < instanceName.length(); ++i) { char c = instanceName.charAt(i); if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_' || c == '.')) { thrownew IllegalArgumentException("Illegal instanceName"); } } }
//如果调用方为系统级应用 if (isCallerSystem) { // Hacky kind of thing -- allow system stuff to tell us // what they are, so we can report this elsewhere for // others to know why certain services are running. service.setDefusable(true); clientIntent = service.getParcelableExtra(Intent.EXTRA_CLIENT_INTENT); if (clientIntent != null) { clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0); if (clientLabel != 0) { // There are no useful extras in the intent, trash them. // System code calling with this stuff just needs to know // this will happen. service = service.cloneFilter(); } } }
//像对待Activity一样对待该Service //需要校验调用方应用是否具有MANAGE_ACTIVITY_STACKS权限 if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { mAm.enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, "BIND_TREAT_LIKE_ACTIVITY"); }
//此标志仅用于系统调整IMEs(以及与顶层App密切合作的其他跨进程的用户可见组件)的调度策略,仅限系统级App使用 if ((flags & Context.BIND_SCHEDULE_LIKE_TOP_APP) != 0 && !isCallerSystem) { thrownew SecurityException("Non-system caller (pid=" + Binder.getCallingPid() + ") set BIND_SCHEDULE_LIKE_TOP_APP when binding service " + service); }
//允许绑定Service的应用程序管理白名单,仅限系统级App使用 if ((flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0 && !isCallerSystem) { thrownew SecurityException( "Non-system caller " + caller + " (pid=" + Binder.getCallingPid() + ") set BIND_ALLOW_WHITELIST_MANAGEMENT when binding service " + service); }
//允许绑定到免安装应用提供的服务,仅限系统级App使用 if ((flags & Context.BIND_ALLOW_INSTANT) != 0 && !isCallerSystem) { thrownew SecurityException( "Non-system caller " + caller + " (pid=" + Binder.getCallingPid() + ") set BIND_ALLOW_INSTANT when binding service " + service); }
//查找相应的Service ServiceLookupResult res = retrieveServiceLocked(service, instanceName, resolvedType, callingPackage, Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg, isBindExternal, allowInstant); if (res == null) { return0; } if (res.record == null) { return -1; } ServiceRecord s = res.record; boolean permissionsReviewRequired = false;
// If permissions need a review before any of the app components can run, // we schedule binding to the service but do not start its process, then // we launch a review activity to which is passed a callback to invoke // when done to start the bound service's process to completing the binding. //如果需要用户手动确认授权 if (mAm.getPackageManagerInternalLocked().isPermissionsReviewRequired( s.packageName, s.userId)) {
permissionsReviewRequired = true;
// Show a permission review UI only for binding from a foreground app //只有调用方进程在前台才可以显示授权弹窗 if (!callerFg) { return0; }
final ServiceRecord serviceRecord = s; final Intent serviceIntent = service;
//用户手动确认授权后执行的回调 RemoteCallback callback = new RemoteCallback( new RemoteCallback.OnResultListener() { @Override publicvoidonResult(Bundle result){ synchronized(mAm) { finallong identity = Binder.clearCallingIdentity(); try { if (!mPendingServices.contains(serviceRecord)) { return; } // If there is still a pending record, then the service // binding request is still valid, so hook them up. We // proceed only if the caller cleared the review requirement // otherwise we unbind because the user didn't approve. //二次检查权限 if (!mAm.getPackageManagerInternalLocked() .isPermissionsReviewRequired( serviceRecord.packageName, serviceRecord.userId)) { try { //拉起服务,如果服务未创建,则会创建服务并调用其onCreate方法 //如果服务已创建则什么都不会做 bringUpServiceLocked(serviceRecord, serviceIntent.getFlags(), callerFg, false, false); } catch (RemoteException e) { /* ignore - local call */ } } else { //无相应权限则解绑Service unbindServiceLocked(connection); } } finally { Binder.restoreCallingIdentity(identity); } } } });
final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); intent.putExtra(Intent.EXTRA_PACKAGE_NAME, s.packageName); intent.putExtra(Intent.EXTRA_REMOTE_CALLBACK, callback);
try { //取消之前的Service重启任务(如果有) if (unscheduleServiceRestartLocked(s, callerApp.info.uid, false)) { if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "BIND SERVICE WHILE RESTART PENDING: " + s); }
if ((flags&Context.BIND_AUTO_CREATE) != 0) { s.lastActivity = SystemClock.uptimeMillis(); //如果是第一次绑定的话,设置跟踪器 if (!s.hasAutoCreateConnections()) { // This is the first binding, let the tracker know. ServiceState stracker = s.getTracker(); if (stracker != null) { stracker.setBound(true, mAm.mProcessStats.getMemFactorLocked(), s.lastActivity); } } }
//绑定的服务代表受保护的系统组件,因此必须对其应用关联做限制 if ((flags & Context.BIND_RESTRICT_ASSOCIATIONS) != 0) { mAm.requireAllowedAssociationsLocked(s.appInfo.packageName); }
//建立调用方与服务方之间的关联 mAm.startAssociationLocked(callerApp.uid, callerApp.processName, callerApp.getCurProcState(), s.appInfo.uid, s.appInfo.longVersionCode, s.instanceName, s.processName); // Once the apps have become associated, if one of them is caller is ephemeral // the target app should now be able to see the calling app mAm.grantImplicitAccess(callerApp.userId, service, callerApp.uid, UserHandle.getAppId(s.appInfo.uid));
//查询App绑定信息 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); //创建连接信息 ConnectionRecord c = new ConnectionRecord(b, activity, connection, flags, clientLabel, clientIntent, callerApp.uid, callerApp.processName, callingPackage);
//更新flag以及进程优先级 if (s.app != null) { if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { s.app.treatLikeActivity = true; } if (s.whitelistManager) { s.app.whitelistManager = true; } // This could have made the service more important. mAm.updateLruProcessLocked(s.app, (callerApp.hasActivitiesOrRecentTasks() && s.app.hasClientActivities()) || (callerApp.getCurProcState() <= ActivityManager.PROCESS_STATE_TOP && (flags & Context.BIND_TREAT_LIKE_ACTIVITY) != 0), b.client); mAm.updateOomAdjLocked(s.app, OomAdjuster.OOM_ADJ_REASON_BIND_SERVICE); }
if (s.app != null && b.intent.received) { // Service is already running, so we can immediately // publish the connection. //如果服务之前就已经在运行,即Service.onBind方法已经被执行,返回的IBinder对象也已经被保存 //调用LoadedApk$ServiceDispatcher$InnerConnection.connected方法 //回调ServiceConnection.onServiceConnected方法 c.conn.connected(s.name, b.intent.binder, false);
// If this is the first app connected back to this binding, // and the service had previously asked to be told when // rebound, then do so. //当服务解绑,调用到Service.onUnbind方法时返回true,此时doRebind变量就会被赋值为true //此时,当再次建立连接时,服务会回调Service.onRebind方法 if (b.intent.apps.size() == 1 && b.intent.doRebind) { requestServiceBindingLocked(s, b.intent, callerFg, true); } } elseif (!b.intent.requested) { //如果服务是因这次绑定而创建的 //请求执行Service.onBind方法,获取返回的IBinder对象 //发布Service,回调ServiceConnection.onServiceConnected方法 requestServiceBindingLocked(s, b.intent, callerFg, false); }
synchronized (this) { if (mForgotten) { // We unbound before receiving the connection; ignore // any connection received. return; } old = mActiveConnections.get(name); //如果旧的连接信息中的IBinder对象和本次调用传入的IBinder对象是同一个对象 if (old != null && old.binder == service) { // Huh, already have this one. Oh well! return; }
if (service != null) { // A new service is being connected... set it all up. //建立一个新的连接信息 info = new ConnectionInfo(); info.binder = service; info.deathMonitor = new DeathMonitor(name, service); try { //注册Binder死亡通知 service.linkToDeath(info.deathMonitor, 0); //保存本次连接信息 mActiveConnections.put(name, info); } catch (RemoteException e) { // This service was dead before we got it... just // don't do anything with it. //服务已死亡,移除连接信息 mActiveConnections.remove(name); return; } } else { // The named service is being disconnected... clean up. mActiveConnections.remove(name); }
//移除Binder死亡通知 if (old != null) { old.binder.unlinkToDeath(old.deathMonitor, 0); } }
// If there was an old service, it is now disconnected. //回调ServiceConnection.onServiceDisconnected //通知client之前的连接已被断开 if (old != null) { mConnection.onServiceDisconnected(name); } //如果Service死亡需要回调ServiceConnection.onBindingDied通知client服务死亡 if (dead) { mConnection.onBindingDied(name); } // If there is a new viable service, it is now connected. if (service != null) { //回调ServiceConnection.onServiceConnected方法 //告知client已建立连接 mConnection.onServiceConnected(name, service); } else { // The binding machinery worked, but the remote returned null from onBind(). //当Service.onBind方法返回null时,回调ServiceConnection.onNullBinding方法 mConnection.onNullBinding(name); } }