Service stopService-Unbounded Service
ContextImpl#stopService
1480 @Override
1481 public boolean stopService(Intent service) {
1482 warnIfCallingFromSystemProcess();
1483 return stopServiceCommon(service, mUser);
1484 }
ContextImpl#stopServiceCommon
1530 private boolean stopServiceCommon(Intent service, UserHandle user) {
1531 try {
1532 validateServiceIntent(service);
1533 service.prepareToLeaveProcess(this);
1534 int res = ActivityManager.getService().stopService(
1535 mMainThread.getApplicationThread(), service,
1536 service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
1537 if (res < 0) {
1538 throw new SecurityException(
1539 "Not allowed to stop service " + service);
1540 }
1541 return res != 0;
1542 } catch (RemoteException e) {
1543 throw e.rethrowFromSystemServer();
1544 }
1545 }
ActivityManagerService#stopService
18776
18777 @Override
18778 public int stopService(IApplicationThread caller, Intent service,
18779 String resolvedType, int userId) {
18780 enforceNotIsolatedCaller("stopService");
18781 // Refuse possible leaked file descriptors
18782 if (service != null && service.hasFileDescriptors() == true) {
18783 throw new IllegalArgumentException("File descriptors passed in Intent");
18784 }
18785
18786 synchronized(this) {
18787 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18788 }
18789 }
ActiveServices#stopServiceLocked
631 int stopServiceLocked(IApplicationThread caller, Intent service,
632 String resolvedType, int userId) {
633 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "stopService: " + service
634 + " type=" + resolvedType);
635
636 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
637 if (caller != null && callerApp == null) {
638 throw new SecurityException(
639 "Unable to find app for caller " + caller
640 + " (pid=" + Binder.getCallingPid()
641 + ") when stopping service " + service);
642 }
643
644 // If this service is active, make sure it is stopped.
645 ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, null,
646 Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false, false); //找到要stop的ServiceRecord
647 if (r != null) {
648 if (r.record != null) {
649 final long origId = Binder.clearCallingIdentity();
650 try {
651 stopServiceLocked(r.record);
652 } finally {
653 Binder.restoreCallingIdentity(origId);
654 }
655 return 1;
656 }
657 return -1;
658 }
659
660 return 0;
661 }
600 private void stopServiceLocked(ServiceRecord service) {
601 if (service.delayed) { //如果stop的Service当前还是delay状态(如kill Service所在进程时这个Service在delay的队列里)
602 // If service isn't actually running, but is is being held in the
603 // delayed list, then we need to keep it started but note that it
604 // should be stopped once no longer delayed.
605 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Delaying stop of pending: " + service);
606 service.delayedStop = true; //设置delayStop的属性为true
607 return;
608 }
609 synchronized (service.stats.getBatteryStats()) {
610 service.stats.stopRunningLocked();
611 }
612 service.startRequested = false; //更新ServiceRecord的状态信息
613 if (service.tracker != null) {
614 service.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
615 SystemClock.uptimeMillis());
616 }
617 service.callStart = false;
627 // END
628 bringDownServiceIfNeededLocked(service, isKnowConn, false);
629 }
ActiveServices#bringDownServiceIfNeededLocked
在必要条件下调用bringDownServiceLocked
2545 private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
2546 boolean hasConn) {
2547 //Slog.i(TAG, "Bring down service:");
2548 //r.dump(" ");
2549
2550 if (isServiceNeededLocked(r, knowConn, hasConn)) { //判断服务是否还有存在的必要,如果还有必要存在,那么那直接return
2551 return;
2552 }
2553
2554 // Are we in the process of launching?
2555 if (mPendingServices.contains(r)) { //Service还未启动,不需要停止,直接return;在bringUpServiceLocked中mPendingServices.add(r),如果启动失败,肯定不会添加;
//适用于一开始Service所在进程都没启动的情况;mPendingServices是代表服务所在进程启动后,待启动的Service
2556 return;
2557 }
2558
2559 bringDownServiceLocked(r);
2560 }
ActiveServices#isServiceNeededLocked
2527 private final boolean isServiceNeededLocked(ServiceRecord r, boolean knowConn,
2528 boolean hasConn) {
2529 // Are we still explicitly being asked to run?
//在进入bringDownServiceIfNeededLocked函数前,startRequested已经置为false了
2530 if (r.startRequested) {
2531 return true;
2532 }
2533
2534 // Is someone still bound to us keeping us running?
2535 if (!knowConn) {
//如果其它客户端,携带BIND_AUTO_CREATE标志,绑定过该Service,那么hasConn被置为true
2536 hasConn = r.hasAutoCreateConnections();
2537 }
2538 if (hasConn) {
2539 return true;
2540 }
2541
2542 return false;
2543 }
ServiceRecord#hasAutoCreateConnections
395 public boolean hasAutoCreateConnections() {
396 // XXX should probably keep a count of the number of auto-create
397 // connections directly in the service.
398 for (int conni=connections.size()-1; conni>=0; conni--) {
399 ArrayList<ConnectionRecord> cr = connections.valueAt(conni);
400 for (int i=0; i<cr.size(); i++) {
401 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
402 return true;
403 }
404 }
405 }
406 return false;
407 }
通过上述代码,我们知道一个Service如果同时以Bounded Service和Unbounded Service存在, 那么必须解绑后,才能被stopService结束。
ActiveServices#bringDownServiceLocked
2562 private final void bringDownServiceLocked(ServiceRecord r) {
2563 //Slog.i(TAG, "Bring down service:");
2564 //r.dump(" ");
2565
2566 // Report to all of the connections that the service is no longer
2567 // available.
2568 for (int conni=r.connections.size()-1; conni>=0; conni--) {
2569 ArrayList<ConnectionRecord> c = r.connections.valueAt(conni);
2570 for (int i=0; i<c.size(); i++) {
2571 ConnectionRecord cr = c.get(i);
2572 // There is still a connection to the service that is
2573 // being brought down. Mark it as dead.
2574 cr.serviceDead = true;
2575 try {
//从之前的isServiceNeeded函数来看
//只有BIND_AUTO_CREATE创建的ServiceConnection,才能阻止Service被终止
//因此,Service是可以有普通的ServiceConnection的
//通知客户端,Service要被stop了
//其实就是调用客户端自定义的ServiceConnection的onServiceDisconnected接口 (bindService中的逻辑)
//这里是回调操作,做完回调操作后还要做解绑操作
2576 cr.conn.connected(r.name, null, true);
2577 } catch (Exception e) {
2578 Slog.w(TAG, "Failure disconnecting service " + r.name +
2579 " to connection " + c.get(i).conn.asBinder() +
2580 " (in " + c.get(i).binding.client.processName + ")", e);
2581 }
2582 }
2583 }
2584
2585 // Tell the service that it has been unbound.
2586 if (r.app != null && r.app.thread != null) {
2587 for (int i=r.bindings.size()-1; i>=0; i--) {
2588 IntentBindRecord ibr = r.bindings.valueAt(i); // All active bindings to the service. //IntentBindRecord 表示绑定Service时的Intent 参考https://www.jianshu.com/p/04ad8a12d808
/*
其中IntentBindRecord.service 最终会保存绑定的service的ServiceRecord;
IntentBindRecord.intent 就是前面所说的绑定service时设定的参数一致的intent在AMS中的表示Intent.FilterComparison对象;
IntentBindRecord.apps用来记录所有使用该类intetn绑定同一个service的客户端信息。key是客户端进程ProcessRecord,value是AppBindRecord。因为不同的客户端可能使用相同的intent参数来绑定同一个service,所以IntentBindRecord要记录下这些客户端信息;
IntentBindRecord.binder最终保存service的代理binder;
IntentBindRecord.received为true,表明IntentBindRecord.binder已经指向远端service的binder;
IntentBindRecord.requested为false,表明IntentBindRecord.binder还没有指向远端service的binder;
具体见bindService中的流程
*/
2589 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing down binding " + ibr
2590 + ": hasBound=" + ibr.hasBound);//Unbounded Service也可以被绑定,此处执行unBindService相关的工作
2591 if (ibr.hasBound) {
//做解绑操作
2592 try {
2593 bumpServiceExecutingLocked(r, false, "bring down unbind"); //执行命令时,调用bumpServiceExecutingLocked先做更改ServiceRecord状态的操作
//关键在r.executeNesting++; r.executingStart = now; 记录命令次数和执行时间,有一个超时的机制(本次命令执行时间过长,就超时)
2594 mAm.updateOomAdjLocked(r.app, true);
2595 ibr.hasBound = false;
2596 ibr.requested = false;
2597 r.app.thread.scheduleUnbindService(r,
2598 ibr.intent.getIntent()); //调用scheduleUnbindService
2599 } catch (Exception e) {
2600 Slog.w(TAG, "Exception when unbinding service "
2601 + r.shortName, e);
2602 serviceProcessGoneLocked(r);
2603 }
2604 }
2605 }
2606 }
2607
2608 // Check to see if the service had been started as foreground, but being
2609 // brought down before actually showing a notification. That is not allowed. //针对前台Service
2610 if (r.fgRequired) { //postNotifcation中有相关逻辑,在sendServiceArgsLocked中如果r.isForeground为true,代表执行过notification了 r.fgRequired = false;
//如果在执行到stopService时这个值仍未true,代表Service还没有走到post Notification逻辑就stop了,需要将相关进程crash
2611 Slog.w(TAG_SERVICE, "Bringing down service while still waiting for start foreground: "
2612 + r);
2613 r.fgRequired = false;
2614 r.fgWaiting = false;
2615 mAm.mHandler.removeMessages(
2616 ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r);
2617 if (r.app != null) {
2618 Message msg = mAm.mHandler.obtainMessage(
2619 ActivityManagerService.SERVICE_FOREGROUND_CRASH_MSG);
2620 msg.obj = r.app;
2621 msg.getData().putCharSequence(
2622 ActivityManagerService.SERVICE_RECORD_KEY, r.toString());
2623 mAm.mHandler.sendMessage(msg);
2624 }
2625 }
2626
2627 if (DEBUG_SERVICE) {
2628 RuntimeException here = new RuntimeException();
2629 here.fillInStackTrace();
2630 Slog.v(TAG_SERVICE, "Bringing down " + r + " " + r.intent, here);
2631 }
2632 r.destroyTime = SystemClock.uptimeMillis();
2633 if (LOG_SERVICE_START_STOP) {
2634 EventLogTags.writeAmDestroyService(
2635 r.userId, System.identityHashCode(r), (r.app != null) ? r.app.pid : -1);
2636 }
2637
2638 final ServiceMap smap = getServiceMapLocked(r.userId);
2639 ServiceRecord found = smap.mServicesByName.remove(r.name);
2640
2641 // Note when this method is called by bringUpServiceLocked(), the service is not found
2642 // in mServicesByName and found will be null.
2643 if (found != null && found != r) {
2644 // This is not actually the service we think is running... this should not happen,
2645 // but if it does, fail hard.
2646 smap.mServicesByName.put(r.name, found);
2647 throw new IllegalStateException("Bringing down " + r + " but actually running "
2648 + found);
2649 }
2650 smap.mServicesByIntent.remove(r.intent); //清除smap中的缓存
2651 r.totalRestartCount = 0;
2652 unscheduleServiceRestartLocked(r, 0, true);
2653
2654 // Also make sure it is not on the pending list.
2655 for (int i=mPendingServices.size()-1; i>=0; i--) {
2656 if (mPendingServices.get(i) == r) {
2657 mPendingServices.remove(i); //将其从进程的待处理的mPendingServices中remove
2658 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Removed pending: " + r);
2659 }
2660 }
2661
2662 cancelForegroundNotificationLocked(r); //int foregroundId; // Notification ID of last foreground req. 将前台服务的通知取消
2663 if (r.isForeground) { // is service currently in foreground mode?
2664 decActiveForegroundAppLocked(smap, r); //减小前台应用,总之也是对ServiceMap中的缓存进行处理
2665 }
2666 r.isForeground = false;
2667 r.foregroundId = 0;
2668 r.foregroundNoti = null;
2669
2670 // Clear start entries.
2671 r.clearDeliveredStartsLocked();
2672 r.pendingStarts.clear(); //将ServiceRecord中的delivered list和penglist中的startItem都删除
2673
2674 if (r.app != null) {
2675 synchronized (r.stats.getBatteryStats()) {
2676 r.stats.stopLaunchedLocked();
2677 }
2678 r.app.services.remove(r);//Service所在进程清除该ServiceRecord
2679 if (r.whitelistManager) {
2680 updateWhitelistManagerLocked(r.app);
2681 }
2682 if (r.app.thread != null) {
2683 updateServiceForegroundLocked(r.app, false); //如果前台服务被stop了,那么其进程优先级可能需要调整(当进程中不存在其他前台服务时调整)
2684 try {
2685 bumpServiceExecutingLocked(r, false, "destroy"); //开始执行destory,调用bumpServiceExecutingLocked做前面的准备工作
2686 mDestroyingServices.add(r);
2687 r.destroying = true;
2688 mAm.updateOomAdjLocked(r.app, true);
2689 r.app.thread.scheduleStopService(r); //调用ActivityThread的scheduleStopService
2690 } catch (Exception e) {
2691 Slog.w(TAG, "Exception when destroying service "
2692 + r.shortName, e);
2693 serviceProcessGoneLocked(r);
2694 }
2695 } else {
2696 if (DEBUG_SERVICE) Slog.v(
2697 TAG_SERVICE, "Removed service that has no process: " + r);
2698 }
2699 } else {
2700 if (DEBUG_SERVICE) Slog.v(
2701 TAG_SERVICE, "Removed service that is not running: " + r);
2702 }
2703
2704 if (r.bindings.size() > 0) {
2705 r.bindings.clear();
2706 }
2707
2708 if (r.restarter instanceof ServiceRestarter) {
2709 ((ServiceRestarter)r.restarter).setService(null); //清除ServiceRestarter
2710 }
2711
2712 int memFactor = mAm.mProcessStats.getMemFactorLocked();
2713 long now = SystemClock.uptimeMillis();
2714 if (r.tracker != null) {
2715 r.tracker.setStarted(false, memFactor, now);
2716 r.tracker.setBound(false, memFactor, now);
2717 if (r.executeNesting == 0) {
2718 r.tracker.clearCurrentOwner(r, false);
2719 r.tracker = null;
2720 }
2721 }
2722
2723 smap.ensureNotStartingBackgroundLocked(r);//一个服务结束后,可能后台service减少,那么会重新触发ServiceMap的ensureNotStartingBackgroundLocked是否进行delay Service的判断
2724 }
参考 Android O 通知栏的"running in the background"
我们看下其中的decActiveForegroundAppLocked方法
private void decActiveForegroundAppLocked(ServiceMap smap, ServiceRecord r) {
ActiveForegroundApp active = smap.mActiveForegroundApps.get(r.packageName);
if (active != null) {
active.mNumActive--;
if (active.mNumActive <= 0) {
active.mEndTime = SystemClock.elapsedRealtime();
if (foregroundAppShownEnoughLocked(active, active.mEndTime)) {
// Have been active for long enough that we will remove it immediately.
smap.mActiveForegroundApps.remove(r.packageName);
smap.mActiveForegroundAppsChanged = true;
requestUpdateActiveForegroundAppsLocked(smap, 0);
} else if (active.mHideTime < Long.MAX_VALUE){
requestUpdateActiveForegroundAppsLocked(smap, active.mHideTime);
}
}
}
}
该方法主要是移除前台service,根据foregroundAppShownEnoughLocked判断,是否马上移除还是过一段时间移除。
该方法主要在两个地方调用。一个是在setServiceForegroundInnerLocked中调用,当应用调用startForeground,第一个参数设为0时,会走到这个路径。
另一个bringDownServiceLocked,也就是当绑定到该service的数量减小时,会调用该方法。
ActivityThread#scheduleStopService
904 public final void scheduleStopService(IBinder token) {
905 sendMessage(H.STOP_SERVICE, token);
906 }
1730 case STOP_SERVICE:
1731 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
1732 handleStopService((IBinder)msg.obj);
1733 maybeSnapshot();
1734 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1735 break;
ActivityThread#handleStopService
3606 private void handleStopService(IBinder token) {
3607 Service s = mServices.remove(token);
3608 if (s != null) {
3609 try {
3610 if (localLOGV) Slog.v(TAG, "Destroying service " + s);
3611 s.onDestroy(); //调用Service的onDestroy函数
3612 s.detachAndCleanUp();
3613 Context context = s.getBaseContext();
3614 if (context instanceof ContextImpl) {
3615 final String who = s.getClassName();
3616 ((ContextImpl) context).scheduleFinalCleanup(who, "Service"); //进行清除工作
3617 }
3622 QueuedWork.waitToFinish();
3624
3625 try {
3626 ActivityManager.getService().serviceDoneExecuting(
3627 token, SERVICE_DONE_EXECUTING_STOP, 0, 0); //调用serviceDoneExecuting做收尾工作
3628 } catch (RemoteException e) {
3629 throw e.rethrowFromSystemServer();
3630 }
3631 } catch (Exception e) {
3632 if (!mInstrumentation.onException(s, e)) {
3633 throw new RuntimeException(
3634 "Unable to stop service " + s
3635 + ": " + e.toString(), e);
3636 }
3637 Slog.i(TAG, "handleStopService: exception for " + token, e);
3638 }
3639 } else {
3640 Slog.i(TAG, "handleStopService: token=" + token + " not found.");
3641 }
3642 //Slog.i(TAG, "Running services: " + mServices);
3643 }
ContextImpl#scheduleFinalCleanup
2374 final void scheduleFinalCleanup(String who, String what) {
2375 mMainThread.scheduleContextCleanup(this, who, what);
2376 }
ActivityThread#scheduleContextCleanup
2713 final void scheduleContextCleanup(ContextImpl context, String who,
2714 String what) {
2715 ContextCleanupInfo cci = new ContextCleanupInfo();
2716 cci.context = context;
2717 cci.who = who;
2718 cci.what = what;
2719 sendMessage(H.CLEAN_UP_CONTEXT, cci);
2720 }
1747 case CLEAN_UP_CONTEXT:
1748 ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
1749 cci.context.performFinalCleanup(cci.who, cci.what);
1750 break;
ContextImpl#performFinalCleanup
2378 final void performFinalCleanup(String who, String what) {
2379 //Log.i(TAG, "Cleanup up context: " + this);
2380 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
2381 }
LoadedApk#removeContextRegistrations
1049 public void removeContextRegistrations(Context context,
1050 String who, String what) {
1051 final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled();
1052 synchronized (mReceivers) {
1053 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap =
1054 mReceivers.remove(context);
1055 if (rmap != null) {
1056 for (int i = 0; i < rmap.size(); i++) {
1057 LoadedApk.ReceiverDispatcher rd = rmap.valueAt(i);
1058 IntentReceiverLeaked leak = new IntentReceiverLeaked(
1059 what + " " + who + " has leaked IntentReceiver "
1060 + rd.getIntentReceiver() + " that was " +
1061 "originally registered here. Are you missing a " +
1062 "call to unregisterReceiver()?");
1063 leak.setStackTrace(rd.getLocation().getStackTrace());
1064 Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
1065 if (reportRegistrationLeaks) {
1066 StrictMode.onIntentReceiverLeaked(leak);
1067 }
1068 try {
1069 ActivityManager.getService().unregisterReceiver(
1070 rd.getIIntentReceiver());
1071 } catch (RemoteException e) {
1072 throw e.rethrowFromSystemServer();
1073 }
1074 }
1075 }
1076 mUnregisteredReceivers.remove(context);
1077 }
1078
1079 synchronized (mServices) {
1080 //Slog.i(TAG, "Receiver registrations: " + mReceivers);
1081 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap =
1082 mServices.remove(context);
1083 if (smap != null) {
1084 for (int i = 0; i < smap.size(); i++) {
1085 LoadedApk.ServiceDispatcher sd = smap.valueAt(i);
1086 ServiceConnectionLeaked leak = new ServiceConnectionLeaked(
1087 what + " " + who + " has leaked ServiceConnection "
1088 + sd.getServiceConnection() + " that was originally bound here");
1089 leak.setStackTrace(sd.getLocation().getStackTrace());
1090 Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
1091 if (reportRegistrationLeaks) {
1092 StrictMode.onServiceConnectionLeaked(leak);
1093 }
1094 try {
1095 ActivityManager.getService().unbindService(
1096 sd.getIServiceConnection());
1097 } catch (RemoteException e) {
1098 throw e.rethrowFromSystemServer();
1099 }
1100 sd.doForget();
1101 }
1102 }
1103 mUnboundServices.remove(context);
1104 //Slog.i(TAG, "Service registrations: " + mServices);
1105 }
1106 }
scheduleFinalCleanup的工作,主要针对于BroadcastReceiver和Bounded Service, 目的是清理它们在AMS中的相关信息
网友评论