//frameworks/base/services/core/java/com/android/server/am/ActiveServices.java booleanstopServiceTokenLocked(ComponentName className, IBinder token, int startId){ //通过className查找相应的ServiceRecord //在Service启动过程中调用的retrieveServiceLocked方法会查找Service,创建ServiceRecord //并将其添加到Map中,findServiceLocked方法只需要从这个Map中去获取即可 ServiceRecord r = findServiceLocked(className, token, UserHandle.getCallingUserId()); if (r != null) { if (startId >= 0) { // Asked to only stop if done with all work. Note that // to avoid leaks, we will take this as dropping all // start items up to and including this one. //查找startId所对应的已分发的启动项 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false, false); //从已分发启动请求列表中移除 if (si != null) { while (r.deliveredStarts.size() > 0) { ServiceRecord.StartItem cur = r.deliveredStarts.remove(0); cur.removeUriPermissionsLocked(); if (cur == si) { break; } } }
//如果传入的启动ID不是Service最后一次启动的ID,则不能停止服务 //ps:每次启动Service,startId都会递增,初始值为1 if (r.getLastStartId() != startId) { returnfalse; } }
// Check to see if the service had been started as foreground, but being // brought down before actually showing a notification. That is not allowed. //如果此Service是以前台服务的形式启动,并且当前还尚未成为前台服务 if (r.fgRequired) { r.fgRequired = false; r.fgWaiting = false; ... //记录 //将前台服务的超时回调取消 mAm.mHandler.removeMessages( ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r); //这种情况直接令App崩溃,杀死应用 if (r.app != null) { Message msg = mAm.mHandler.obtainMessage( ActivityManagerService.SERVICE_FOREGROUND_CRASH_MSG); msg.obj = r.app; msg.getData().putCharSequence( ActivityManagerService.SERVICE_RECORD_KEY, r.toString()); mAm.mHandler.sendMessage(msg); } }
//从缓存中移除ServiceRecord final ServiceMap smap = getServiceMapLocked(r.userId); ServiceRecord found = smap.mServicesByInstanceName.remove(r.instanceName);
// Note when this method is called by bringUpServiceLocked(), the service is not found // in mServicesByInstanceName and found will be null. if (found != null && found != r) { // This is not actually the service we think is running... this should not happen, // but if it does, fail hard. //如果找到的服务不是我们目前停止的服务,应该是一个不可能的情况 //碰到这种情况,将ServiceRecord重新放回去并抛出异常 smap.mServicesByInstanceName.put(r.instanceName, found); thrownew IllegalStateException("Bringing down " + r + " but actually running " + found); } //清除ServiceRecord smap.mServicesByIntent.remove(r.intent); r.totalRestartCount = 0; //取消之前的Service重启任务(如果有) unscheduleServiceRestartLocked(r, 0, true);
// Also make sure it is not on the pending list. //从待启动Service列表中移除 for (int i=mPendingServices.size()-1; i>=0; i--) { if (mPendingServices.get(i) == r) { mPendingServices.remove(i); } }
//frameworks/base/services/core/java/com/android/server/am/ActiveServices.java intstopServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int userId){ final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller); if (caller != null && callerApp == null) { thrownew SecurityException( "Unable to find app for caller " + caller + " (pid=" + Binder.getCallingPid() + ") when stopping service " + service); }
// If this service is active, make sure it is stopped. //查找相应的Service,其中入参createIfNeeded为false,所以如果从缓存中找不到ServiceRecord的话则会直接返回null ServiceLookupResult r = retrieveServiceLocked(service, null, resolvedType, null, Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false, false, false); if (r != null) { if (r.record != null) { finallong origId = Binder.clearCallingIdentity(); try { //接着处理停止服务 stopServiceLocked(r.record); } finally { Binder.restoreCallingIdentity(origId); } return1; } return -1; }
return0; }
privatevoidstopServiceLocked(ServiceRecord service){ if (service.delayed) { // If service isn't actually running, but is being held in the // delayed list, then we need to keep it started but note that it // should be stopped once no longer delayed. service.delayedStop = true; return; } ... //统计信息记录
finallong origId = Binder.clearCallingIdentity(); try { //遍历连接 while (clist.size() > 0) { ConnectionRecord r = clist.get(0); //移除连接 removeConnectionLocked(r, null, null); //removeConnectionLocked方法会将此ConnectionRecord从连接列表中移除 //如果此ConnectionRecord仍然存在的话,是一个严重的错误,这里再移除一次 if (clist.size() > 0 && clist.get(0) == r) { // In case it didn't get removed above, do it now. Slog.wtf(TAG, "Connection " + r + " not removed for binder " + binder); clist.remove(0); }
if (r.binding.service.app != null) { if (r.binding.service.app.whitelistManager) { updateWhitelistManagerLocked(r.binding.service.app); } // This could have made the service less important. if ((r.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { r.binding.service.app.treatLikeActivity = true; mAm.updateLruProcessLocked(r.binding.service.app, r.binding.service.app.hasClientActivities() || r.binding.service.app.treatLikeActivity, null); } } }
//如果调用方App没有其他连接和Service绑定 //则将整个AppBindRecord移除 if (b.connections.size() == 0) { b.intent.apps.remove(b.client); }
if (!c.serviceDead) { //如果服务端进程存活并且没有其他连接绑定了,同时服务还处在绑定关系中(尚未回调过Service.onUnbind) if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0 && b.intent.hasBound) { try { bumpServiceExecutingLocked(s, false, "unbind"); if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0 && s.app.setProcState <= ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { // If this service's process is not already in the cached list, // then update it in the LRU list here because this may be causing // it to go down there and we want it to start out near the top. mAm.updateLruProcessLocked(s.app, false, null); } mAm.updateOomAdjLocked(s.app, true, OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE); //标记为未绑定 b.intent.hasBound = false; // Assume the client doesn't want to know about a rebind; // we will deal with that later if it asks for one. b.intent.doRebind = false; //回到App进程,调度执行Service的unbind操作 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent()); } catch (Exception e) { serviceProcessGoneLocked(s); } }
// If unbound while waiting to start and there is no connection left in this service, // remove the pending service if (s.getConnections().isEmpty()) { mPendingServices.remove(s); }
//frameworks/base/services/core/java/com/android/server/am/ServiceRecord.java public AppBindRecord retrieveAppBindingLocked(Intent intent, ProcessRecord app){ Intent.FilterComparison filter = new Intent.FilterComparison(intent); IntentBindRecord i = bindings.get(filter); if (i == null) { i = new IntentBindRecord(this, filter); bindings.put(filter, i); } AppBindRecord a = i.apps.get(app); if (a != null) { return a; } a = new AppBindRecord(this, i, app); i.apps.put(app, a); return a; }
// Are we in the process of launching? //不要停止正在启动中的Service if (mPendingServices.contains(r)) { return; }
//继续停止服务 bringDownServiceLocked(r); }
privatefinalbooleanisServiceNeededLocked(ServiceRecord r, boolean knowConn, boolean hasConn){ // Are we still explicitly being asked to run? //Service之前是否通过startService启动过并且未stop if (r.startRequested) { returntrue; }
// Is someone still bound to us keeping us running? //这里我们传入的是true //因为我们之前已经做了检查,知道了是否还有其他auto-create的连接 if (!knowConn) { hasConn = r.hasAutoCreateConnections(); } //如果还有其他auto-create的连接 //则此服务还被需要 if (hasConn) { returntrue; }
//frameworks/base/services/core/java/com/android/server/am/ActiveServices.java privatefinalvoidbringDownServiceLocked(ServiceRecord r){ //断开所有连接 ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections(); for (int conni = connections.size() - 1; conni >= 0; conni--) { ArrayList<ConnectionRecord> c = connections.valueAt(conni); for (int i=0; i<c.size(); i++) { ConnectionRecord cr = c.get(i); // There is still a connection to the service that is // being brought down. Mark it as dead. //将服务标记为死亡 cr.serviceDead = true; cr.stopAssociation(); //回调ServiceConnection各种方法 //通知client服务断开连接以及死亡 cr.conn.connected(r.name, null, true); } }
// Tell the service that it has been unbound. //通知Service解除绑定 if (r.app != null && r.app.thread != null) { boolean needOomAdj = false; //遍历所有连接,解除绑定 for (int i = r.bindings.size() - 1; i >= 0; i--) { IntentBindRecord ibr = r.bindings.valueAt(i); //如果还处在绑定关系中(尚未回调过Service.onUnbind) if (ibr.hasBound) { try { //记录Service执行操作并设置超时回调 //前台服务超时时间为20s,后台服务超时时间为200s bumpServiceExecutingLocked(r, false, "bring down unbind"); needOomAdj = true; //标记为未绑定 ibr.hasBound = false; ibr.requested = false; //回到App进程,调度执行Service的unbind操作 r.app.thread.scheduleUnbindService(r, ibr.intent.getIntent()); } catch (Exception e) { needOomAdj = false; serviceProcessGoneLocked(r); break; } } } //更新服务端进程优先级 if (needOomAdj) { mAm.updateOomAdjLocked(r.app, true, OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE); } } ... //和上文相同 }
synchronized (this) { //被标记为遗忘则不处理任何事情 //调用unbindService就会将这个标志设为true 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,或者Service停止时 //回调ServiceConnection.onNullBinding方法 mConnection.onNullBinding(name); } }
//frameworks/base/services/core/java/com/android/server/am/ActiveServices.java voidunbindFinishedLocked(ServiceRecord r, Intent intent, boolean doRebind){ finallong origId = Binder.clearCallingIdentity(); try { if (r != null) { Intent.FilterComparison filter = new Intent.FilterComparison(intent); IntentBindRecord b = r.bindings.get(filter);
boolean inDestroying = mDestroyingServices.contains(r); if (b != null) { //服务unbind的前提就是IntentBindRecord.apps.size == 0 if (b.apps.size() > 0 && !inDestroying) { ... } else { // Note to tell the service the next time there is // a new client. //将doRebind标记置为true,下一次再次建立连接时 //服务会回调Service.onRebind方法 b.doRebind = true; } }
//frameworks/base/services/core/java/com/android/server/am/ActiveServices.java intbindServiceLocked(IApplicationThread caller, IBinder token, Intent service, String resolvedType, final IServiceConnection connection, int flags, String instanceName, String callingPackage, finalint userId) throws TransactionTooLargeException { ... 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); } ... }
// Find any running services associated with this app and stop if needed. //清理和此Task有关联的服务 final Message msg = PooledLambda.obtainMessage(ActivityManagerInternal::cleanUpServices, mService.mAmInternal, task.mUserId, component, new Intent(task.getBaseIntent())); mService.mH.sendMessage(msg);
//如果不需要杀死进程,到这里就为止了 if (!killProcess) { return; }
// Determine if the process(es) for this task should be killed. final String pkg = component.getPackageName(); ArrayList<Object> procsToKill = new ArrayList<>(); ArrayMap<String, SparseArray<WindowProcessController>> pmap = mService.mProcessNames.getMap(); //遍历App进程,确定要杀死的进程 for (int i = 0; i < pmap.size(); i++) { SparseArray<WindowProcessController> uids = pmap.valueAt(i); for (int j = 0; j < uids.size(); j++) { WindowProcessController proc = uids.valueAt(j); //不要杀死其他用户下的进程 if (proc.mUserId != task.mUserId) { // Don't kill process for a different user. continue; } //不要杀死首页进程 //HomeProcess指的是含有分类为android.intent.category.HOME的进程 //也就是能成为首页Launcher的进程 if (proc == mService.mHomeProcess) { // Don't kill the home process along with tasks from the same package. continue; } //不要杀死和这个Task无关的进程 if (!proc.mPkgList.contains(pkg)) { // Don't kill process that is not associated with this task. continue; }
//如果这个进程有Activity在不同的Task里,并且这个Task也在最近任务里 //或者有Activity还没有被停止,则不要杀死进程 if (!proc.shouldKillProcessForRemovedTask(task)) { // Don't kill process(es) that has an activity in a different task that is also // in recents, or has an activity not stopped. return; }
//有前台服务的话不要杀死进程 if (proc.hasForegroundServices()) { // Don't kill process(es) with foreground service. return; }
// Add process to kill list. procsToKill.add(proc); } }
// Kill the running processes. Post on handle since we don't want to hold the service lock // while calling into AM. //杀死进程 final Message m = PooledLambda.obtainMessage( ActivityManagerInternal::killProcessesForRemovedTask, mService.mAmInternal, procsToKill); mService.mH.sendMessage(m); }
//frameworks/base/services/core/java/com/android/server/am/ActiveServices.java voidcleanUpServices(int userId, ComponentName component, Intent baseIntent){ ArrayList<ServiceRecord> services = new ArrayList<>(); //获得此用户下所有的活动Service ArrayMap<ComponentName, ServiceRecord> alls = getServicesLocked(userId); //筛选出此Task下的所有活动Service for (int i = alls.size() - 1; i >= 0; i--) { ServiceRecord sr = alls.valueAt(i); if (sr.packageName.equals(component.getPackageName())) { services.add(sr); } }
// Take care of any running services associated with the app. for (int i = services.size() - 1; i >= 0; i--) { ServiceRecord sr = services.get(i); if (sr.startRequested) { if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) { //如果在manifest里设置了stopWithTask,那么会直接停止Service stopServiceLocked(sr); } else { //如果没有设置stopWithTask的话,则会回调Service.onTaskRemoved方法 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true, sr.getLastStartId(), baseIntent, null, 0)); if (sr.app != null && sr.app.thread != null) { // We always run in the foreground, since this is called as // part of the "remove task" UI operation. try { sendServiceArgsLocked(sr, true, false); } catch (TransactionTooLargeException e) { // Ignore, keep going. } } } } } }
//frameworks/base/core/java/android/app/ActivityThread.java privatevoidhandleServiceArgs(ServiceArgsData data){ Service s = mServices.get(data.token); if (s != null) { try { ... 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; }
//frameworks/base/services/core/java/com/android/server/am/ActiveServices.java voidserviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res){ boolean inDestroying = mDestroyingServices.contains(r); if (r != null) { if (type == ActivityThread.SERVICE_DONE_EXECUTING_START) { // This is a call from a service start... take care of // book-keeping. r.callStart = true; switch (res) { case Service.START_STICKY_COMPATIBILITY: case Service.START_STICKY: { // We are done with the associated start arguments. r.findDeliveredStart(startId, false, true); // Don't stop if killed. r.stopIfKilled = false; break; } case Service.START_NOT_STICKY: { // We are done with the associated start arguments. r.findDeliveredStart(startId, false, true); if (r.getLastStartId() == startId) { // There is no more work, and this service // doesn't want to hang around if killed. r.stopIfKilled = true; } break; } case Service.START_REDELIVER_INTENT: { // We'll keep this item until they explicitly // call stop for it, but keep track of the fact // that it was delivered. ServiceRecord.StartItem si = r.findDeliveredStart(startId, false, false); if (si != null) { si.deliveryCount = 0; si.doneExecutingCount++; // Don't stop if killed. r.stopIfKilled = true; } break; } case Service.START_TASK_REMOVED_COMPLETE: { // Special processing for onTaskRemoved(). Don't // impact normal onStartCommand() processing. r.findDeliveredStart(startId, true, true); break; } default: thrownew IllegalArgumentException( "Unknown service start result: " + res); } if (res == Service.START_STICKY_COMPATIBILITY) { r.callStart = false; } } elseif (type == ActivityThread.SERVICE_DONE_EXECUTING_STOP) { ... } ... } else { ... } }
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java privatefinalclassAppDeathRecipientimplementsIBinder.DeathRecipient{ final ProcessRecord mApp; finalint mPid; final IApplicationThread mAppThread;
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java finalvoidappDiedLocked(ProcessRecord app, int pid, IApplicationThread thread, boolean fromBinderDied, String reason){ // First check if this ProcessRecord is actually active for the pid. //检查pid所属ProcessRecord是否与传入ProcessRecord相符 synchronized (mPidsSelfLocked) { ProcessRecord curProc = mPidsSelfLocked.get(pid); if (curProc != app) { return; } }
... //记录电池统计信息
//如果App进程尚未死亡的话,杀死进程 if (!app.killed) { if (!fromBinderDied) { killProcessQuiet(pid); mProcessList.noteAppKill(app, ApplicationExitInfo.REASON_OTHER, ApplicationExitInfo.SUBREASON_UNKNOWN, reason); } ProcessList.killProcessGroup(app.uid, pid); app.killed = true; }
// Clean up already done if the process has been re-started. if (app.pid == pid && app.thread != null && app.thread.asBinder() == thread.asBinder()) { //一般情况下非自动化测试,先置为true boolean doLowMem = app.getActiveInstrumentation() == null; boolean doOomAdj = doLowMem; if (!app.killedByAm) { //不通过AMS杀死的进程,一般就是被 Low Memory Killer (LMK) 杀死的 ... //报告信息 //被LMK杀死,说明系统内存不足 mAllowLowerMemLevel = true; } else { //通过AMS杀死的进程 // Note that we always want to do oom adj to update our state with the // new number of procs. mAllowLowerMemLevel = false; //正常情况下非内存不足 doLowMem = false; } ... //事件记录 //继续处理App进程死亡 handleAppDiedLocked(app, false, true);
//调整进程优先级 if (doOomAdj) { updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_PROCESS_END); } //当因为内存不足而杀死App进程时 //调用App层各处的的onLowMemory方法,释放内存 if (doLowMem) { doLowMemReportIfNeededLocked(app); } } elseif (app.pid != pid) { //新进程已启动 // A new process has already been started. ... //报告记录信息 } ... }
finalvoidkillServicesLocked(ProcessRecord app, boolean allowRestart){ // Clean up any connections this application has to other services. //清理所有连接 for (int i = app.connections.size() - 1; i >= 0; i--) { ConnectionRecord r = app.connections.valueAt(i); removeConnectionLocked(r, app, null); } updateServiceConnectionActivitiesLocked(app); app.connections.clear();
app.whitelistManager = false;
// Clear app state from services. //遍历所有正在运行中的服务 for (int i = app.numberOfRunningServices() - 1; i >= 0; i--) { ServiceRecord sr = app.getRunningServiceAt(i); synchronized (sr.stats.getBatteryStats()) { sr.stats.stopLaunchedLocked(); } if (sr.app != app && sr.app != null && !sr.app.isPersistent()) { //记录服务已停止 sr.app.stopService(sr); //更新绑定的客户端uids sr.app.updateBoundClientUids(); } sr.setProcess(null); sr.isolatedProc = null; sr.executeNesting = 0; sr.forceClearTracker(); if (mDestroyingServices.remove(sr)) { if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "killServices remove destroying " + sr); }
finalint numClients = sr.bindings.size(); for (int bindingi=numClients-1; bindingi>=0; bindingi--) { IntentBindRecord b = sr.bindings.valueAt(bindingi); //释放对服务Binder的引用 b.binder = null; //重置 b.requested = b.received = b.hasBound = false; // If this binding is coming from a cached process and is asking to keep // the service created, then we'll kill the cached process as well -- we // don't want to be thrashing around restarting processes that are only // there to be cached. ... //遍历客户端进程(实际上没做任何事) } }
// Now do remaining service cleanup. for (int i = app.numberOfRunningServices() - 1; i >= 0; i--) { ServiceRecord sr = app.getRunningServiceAt(i);
// Unless the process is persistent, this process record is going away, // so make sure the service is cleaned out of it. //非持久化进程 if (!app.isPersistent()) { //记录服务已停止 app.stopService(sr); //更新绑定的客户端uids app.updateBoundClientUids(); }
// Sanity check: if the service listed for the app is not one // we actually are maintaining, just let it drop. //一致性检查 final ServiceRecord curRec = smap.mServicesByInstanceName.get(sr.instanceName); if (curRec != sr) { if (curRec != null) { Slog.wtf(TAG, "Service " + sr + " in process " + app + " not same as in map: " + curRec); } continue; }
// Any services running in the application may need to be placed // back in the pending list. //允许重启,但Service崩溃的次数超出重试上限(默认为16),并且它不是系统应用 if (allowRestart && sr.crashCount >= mAm.mConstants.BOUND_SERVICE_MAX_CRASH_RETRY && (sr.serviceInfo.applicationInfo.flags &ApplicationInfo.FLAG_PERSISTENT) == 0) { ... //记录 //停止服务 bringDownServiceLocked(sr); } elseif (!allowRestart || !mAm.mUserController.isUserRunning(sr.userId, 0)) { //不允许重启或者服务进程所在用户不在运行,停止服务 bringDownServiceLocked(sr); } else { //尝试调度重启服务 finalboolean scheduled = scheduleServiceRestartLocked(sr, true/* allowCancel */);
// Should the service remain running? Note that in the // extreme case of so many attempts to deliver a command // that it failed we also will stop it here. if (!scheduled) { //未调度重启 //停止服务 bringDownServiceLocked(sr); } elseif (sr.canStopIfKilled(false/* isStartCanceled */)) { // Update to stopped state because the explicit start is gone. The service is // scheduled to restart for other reason (e.g. connections) so we don't bring // down it. //将服务的启动状态更新为停止 sr.startRequested = false; ... //记录 } } }
//不允许重启的话 if (!allowRestart) { //停止所有服务 app.stopAllServices(); //清理绑定的客户端uids app.clearBoundClientUids();
// Make sure there are no more restarting services for this process. //确保这个进程不再会重启服务,清理所有待重启待启动的服务 for (int i=mRestartingServices.size()-1; i>=0; i--) { ServiceRecord r = mRestartingServices.get(i); if (r.processName.equals(app.processName) && r.serviceInfo.applicationInfo.uid == app.info.uid) { mRestartingServices.remove(i); clearRestartingIfNeededLocked(r); } } for (int i=mPendingServices.size()-1; i>=0; i--) { ServiceRecord r = mPendingServices.get(i); if (r.processName.equals(app.processName) && r.serviceInfo.applicationInfo.uid == app.info.uid) { mPendingServices.remove(i); } } }
// Make sure we have no more records on the stopping list. //清理所有停止中的服务 int i = mDestroyingServices.size(); while (i > 0) { i--; ServiceRecord sr = mDestroyingServices.get(i); if (sr.app == app) { sr.forceClearTracker(); mDestroyingServices.remove(i); } }
//一致性检查 ServiceMap smap = getServiceMapLocked(r.userId); if (smap.mServicesByInstanceName.get(r.instanceName) != r) { ServiceRecord cur = smap.mServicesByInstanceName.get(r.instanceName); Slog.wtf(TAG, "Attempting to schedule restart of " + r + " when found in map: " + cur); returnfalse; }
finallong now = SystemClock.uptimeMillis();
final String reason; if ((r.serviceInfo.applicationInfo.flags &ApplicationInfo.FLAG_PERSISTENT) == 0) { //对于非系统应用 //服务至少要过多长时间才能重启,默认1000ms long minDuration = mAm.mConstants.SERVICE_RESTART_DURATION; //服务被杀死重启后需要运行多长时间,默认60s long resetTime = mAm.mConstants.SERVICE_RESET_RUN_DURATION; boolean canceled = false;
// Any delivered but not yet finished starts should be put back // on the pending list. //对应着返回值为START_REDELIVER_INTENT的情况 finalint N = r.deliveredStarts.size(); if (N > 0) { for (int i=N-1; i>=0; i--) { ServiceRecord.StartItem si = r.deliveredStarts.get(i); si.removeUriPermissionsLocked(); if (si.intent == null) { // We'll generate this again if needed. } elseif (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) { //如果该启动项的失败次数小于最大容忍次数 //MAX_DELIVERY_COUNT默认为3 //MAX_DONE_EXECUTING_COUNT默认为6 r.pendingStarts.add(0, si); //这种情况下延时是现在距离启动时间的两倍 long dur = SystemClock.uptimeMillis() - si.deliveredTime; dur *= 2; if (minDuration < dur) minDuration = dur; if (resetTime < dur) resetTime = dur; } else { //如果该启动项的失败次数大于等于最大容忍次数 canceled = true; } } r.deliveredStarts.clear(); }
r.totalRestartCount++; if (r.restartDelay == 0) { //第一次重启的情况 r.restartCount++; r.restartDelay = minDuration; } elseif (r.crashCount > 1) { //Service所在进程在Service运行过程中发生崩溃导致重启的话 //重启延时为 30min * (崩溃次数 - 1) r.restartDelay = mAm.mConstants.BOUND_SERVICE_CRASH_RESTART_DURATION * (r.crashCount - 1); } else { //非第一次重启的情况 // If it has been a "reasonably long time" since the service // was started, then reset our restart duration back to // the beginning, so we don't infinitely increase the duration // on a service that just occasionally gets killed (which is // a normal case, due to process being killed to reclaim memory). if (now > (r.restartTime+resetTime)) { //如果服务重启后运行达到了一定时间,则重启延时为 r.restartCount = 1; r.restartDelay = minDuration; } else { //如果服务重启后运行没有达到一定时间(短时间内又要重启) //则增长重启延时,默认因子为4 r.restartDelay *= mAm.mConstants.SERVICE_RESTART_DURATION_FACTOR; if (r.restartDelay < minDuration) { r.restartDelay = minDuration; } } }
//确定重启时间 r.nextRestartTime = now + r.restartDelay;
// Make sure that we don't end up restarting a bunch of services // all at the same time. //确保不会在同一时间启动大量服务 boolean repeat; do { repeat = false; finallong restartTimeBetween = mAm.mConstants.SERVICE_MIN_RESTART_TIME_BETWEEN; for (int i=mRestartingServices.size()-1; i>=0; i--) { ServiceRecord r2 = mRestartingServices.get(i); if (r2 != r && r.nextRestartTime >= (r2.nextRestartTime-restartTimeBetween) && r.nextRestartTime < (r2.nextRestartTime+restartTimeBetween)) { r.nextRestartTime = r2.nextRestartTime + restartTimeBetween; r.restartDelay = r.nextRestartTime - now; repeat = true; break; } } } while (repeat);
} else { //对于系统进程,立马重启 // Persistent processes are immediately restarted, so there is no // reason to hold of on restarting their services. r.totalRestartCount++; r.restartCount = 0; r.restartDelay = 0; r.nextRestartTime = now; reason = "persistent"; }
//frameworks/base/services/core/java/com/android/server/am/ActiveServices.java finalvoidperformServiceRestartLocked(ServiceRecord r){ if (!mRestartingServices.contains(r)) { return; } if (!isServiceNeededLocked(r, false, false)) { // Paranoia: is this service actually needed? In theory a service that is not // needed should never remain on the restart list. In practice... well, there // have been bugs where this happens, and bad things happen because the process // ends up just being cached, so quickly killed, then restarted again and again. // Let's not let that happen. Slog.wtf(TAG, "Restarting service that is not needed: " + r); return; } try { //参考上一篇文章,Service启动流程 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true, false); } catch (TransactionTooLargeException e) { // Ignore, it's been logged and nothing upstack cares. } }