本文基于 Android 7.1.1 源码分析,转载请说明出处!
0 综述 我们通过 startService 启动的服务,需要通过 stopService 来停止:
1 context.stopService(intent); 
 
以前我们只是会调用,但是其底层的调用到底是什么样的呢?知其然知其所以然,今天我们就来学习下 stopService 的过程!
如果之前并不了解这块逻辑的话,那该如何去学习呢? follow the funtion path!
1 发起端进程 1.1 ContextWrapper.stopService 1 2 3 4 5 6 7 8 9 10 11 12 13 public  class  ContextWrapper  extends  Context  {    Context mBase;     public  ContextWrapper (Context base)  {         mBase = base;     }          @Override      public  boolean  stopService (Intent name)  {         return  mBase.stopService(name);     }      } 
 
ContextWrapper 提供了两个方法来启动 Service,其中一个是隐藏方法:startServiceAsUser!
mBase 是 ContextImpl 对象,继续看!
1.2 ContextImpl.stopService 1 2 3 4 5 6 7 8 9 10 11 class  ContextImpl  extends  Context  {    @Override      public  boolean  stopService (Intent service)  {                           warnIfCallingFromSystemProcess();                  return  stopServiceCommon(service, mUser);     } } 
 
这里调用了 warnIfCallingFromSystemProcess,判断是否是系统进程调用!1 2 3 4 5 6 private  void  warnIfCallingFromSystemProcess ()  {    if  (Process.myUid() == Process.SYSTEM_UID) {         Slog.w(TAG, "Calling a method in the system process without a qualified user: "                  + Debug.getCallers(5 ));     } } 
ContextImpl 和 ContextWrapper 的具体关系,请来看另一博文:Android 系统的 Context 分析,这里我们不再详细说明!
mUser:表示的是当前的设备 user!
最终,调用了 stopServiceCommon 方法;
1.3 ContextImpl.stopServiceCommon 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 private  boolean  stopServiceCommon (Intent service, UserHandle user)  {    try  {         validateServiceIntent(service);         service.prepareToLeaveProcess(this );                           int  res  =  ActivityManagerNative.getDefault().stopService(             mMainThread.getApplicationThread(), service,             service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());         if  (res < 0 ) {             throw  new  SecurityException (                     "Not allowed to stop service "  + service);         }         return  res != 0 ;     } catch  (RemoteException e) {         throw  e.rethrowFromSystemServer();     } } 
 
validateServiceIntent 方法用用来校验启动用的 intent 是否安全:1 2 3 4 5 6 7 8 9 10 11 12 private  void  validateServiceIntent (Intent service)  {    if  (service.getComponent() == null  && service.getPackage() == null ) {         if  (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {             IllegalArgumentException  ex  =  new  IllegalArgumentException (                     "Service Intent must be explicit: "  + service);             throw  ex;         } else  {             Log.w(TAG, "Implicit intents with startService are not safe: "  + service                     + " "  + Debug.getCallers(2 , 3 ));         }     } } 
 如果 intent 既没有设置 component 也没有设置 package,那就要判断一下系统的版本了: 
如果系统版本不低于 L,那就要抛出异常,提示必须是显示启动; 
如果系统版本低于 L,那只提示隐式启动不安全; 
 
接着,调用 ActivityManagerNative.getDefault() 方法,获得 AMS 的代理对象 ActivityManagerProxy!
ActivityManagerProxy 是 ActivityManagerN 的内部类,通过 getDefault 方法创建了对应的单例模式,保存在 ActivityManagerNative 的类变量 getDefault 中!
1.4 ActivityManagerP.stopService 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public  int  stopService (IApplicationThread caller, Intent service,         String resolvedType, int  userId)  throws  RemoteException{     Parcel  data  =  Parcel.obtain();     Parcel  reply  =  Parcel.obtain();     data.writeInterfaceToken(IActivityManager.descriptor);     data.writeStrongBinder(caller != null  ? caller.asBinder() : null );     service.writeToParcel(data, 0 );     data.writeString(resolvedType);     data.writeInt(userId);          mRemote.transact(STOP_SERVICE_TRANSACTION, data, reply, 0 );     reply.readException();     int  res  =  reply.readInt();     reply.recycle();     data.recycle();     return  res; } 
 
通过 binder 进程间通信,进入系统进程,参数分析:
IApplicationThread caller:调用者进程的 ApplicationThread 对象,实现了 IApplicationThread 接口; 
Intent service:启动的 intent; 
String resolvedType:这个 intent 的 MIME 类型; 
String callingPackage:启动者所属包名; 
int userId:设备用户 id; 
 
2 系统进程 接下来,进入系统进程的 ActivityManagerService 中!
首先要进入 ActivityManagerN.onTransact 方法!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 case  STOP_SERVICE_TRANSACTION: {    data.enforceInterface(IActivityManager.descriptor);     IBinder  b  =  data.readStrongBinder();     IApplicationThread  app  =  ApplicationThreadNative.asInterface(b);     Intent  service  =  Intent.CREATOR.createFromParcel(data);     String  resolvedType  =  data.readString();     int  userId  =  data.readInt();          int  res  =  stopService(app, service, resolvedType, userId);     reply.writeNoException();     reply.writeInt(res);     return  true ; } 
2.1 ActivityManagerS.stopService 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @Override public  int  stopService (IApplicationThread caller, Intent service,         String resolvedType, int  userId)  {                  enforceNotIsolatedCaller("stopService" );          if  (service != null  && service.hasFileDescriptors() == true ) {         throw  new  IllegalArgumentException ("File descriptors passed in Intent" );     }     synchronized (this ) {                           return  mServices.stopServiceLocked(caller, service, resolvedType, userId);     } } 
 
mServices 是 ActivityManagerService 的一个内部管理对象,用于管理所有的 Service!
2.2 ActiveServices.stopServiceLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 int  stopServiceLocked (IApplicationThread caller, Intent service,         String resolvedType, int  userId)  {    if  (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "stopService: "  + service             + " type="  + resolvedType);               final  ProcessRecord  callerApp  =  mAm.getRecordForAppLocked(caller);     if  (caller != null  && callerApp == null ) {         throw  new  SecurityException (                 "Unable to find app for caller "  + caller                 + " (pid="  + Binder.getCallingPid()                 + ") when stopping service "  + service);     }          ServiceLookupResult  r  =  retrieveServiceLocked(service, resolvedType, null ,             Binder.getCallingPid(), Binder.getCallingUid(), userId, false , false , false );     if  (r != null ) {         if  (r.record != null ) {             final  long  origId  =  Binder.clearCallingIdentity();             try  {                                               stopServiceLocked(r.record);             } finally  {                 Binder.restoreCallingIdentity(origId);             }             return  1 ;         }         return  -1 ;     }     return  0 ; } 
 
2.2.1 ActiveServices.retrieveServiceLocked 根据 intent 来查询被启动服务的 ServiceRecord 对象,参数传递:
boolean createIfNeeded:传入的是 true; 
boolean callingFromFg:表示是从前台调用,还是后台调用; 
boolean isBindExternal:表示 bind 的是否是 isolated, external 类型的服务,我们这里默认为 false; 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 private  ServiceLookupResult retrieveServiceLocked (Intent service,         String resolvedType, String callingPackage, int  callingPid, int  callingUid, int  userId,         boolean  createIfNeeded, boolean  callingFromFg, boolean  isBindExternal)  {    ServiceRecord  r  =  null ;     if  (DEBUG_SERVICE)         Slog.v(TAG_SERVICE, "retrieveServiceLocked: "  + service             + " type="  + resolvedType + " callingUid="  + callingUid);     userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId, false ,             ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE, "service" , null );          ServiceMap  smap  =  getServiceMap(userId);               final  ComponentName  comp  =  service.getComponent();     if  (comp != null ) {         r = smap.mServicesByName.get(comp);     }          if  (r == null  && !isBindExternal) {         Intent.FilterComparison  filter  =  new  Intent .FilterComparison(service);         r = smap.mServicesByIntent.get(filter);     }               if  (r != null  && (r.serviceInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) != 0              && !callingPackage.equals(r.packageName)) {         r = null ;     }     if  (r == null ) {         try  {                          ResolveInfo  rInfo  =  AppGlobals.getPackageManager().resolveService(service,                     resolvedType, ActivityManagerService.STOCK_PM_FLAGS                             | PackageManager.MATCH_DEBUG_TRIAGED_MISSING,                     userId);                                       ServiceInfo  sInfo  =                  rInfo != null  ? rInfo.serviceInfo : null ;             if  (sInfo == null ) {                 Slog.w(TAG_SERVICE, "Unable to start service "  + service + " U="  + userId +                       ": not found" );                 return  null ;             }             ComponentName  name  =  new  ComponentName (                     sInfo.applicationInfo.packageName, sInfo.name);                                                    if  ((sInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) != 0 ) {                 if  (isBindExternal) {                     if  (!sInfo.exported) {                                                  throw  new  SecurityException ("BIND_EXTERNAL_SERVICE failed, "  + name +                                 " is not exported" );                     }                                                               if  ((sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) == 0 ) {                         throw  new  SecurityException ("BIND_EXTERNAL_SERVICE failed, "  + name +                                 " is not an isolatedProcess" );                     }                                          ApplicationInfo  aInfo  =  AppGlobals.getPackageManager().getApplicationInfo(                             callingPackage, ActivityManagerService.STOCK_PM_FLAGS, userId);                     if  (aInfo == null ) {                         throw  new  SecurityException ("BIND_EXTERNAL_SERVICE failed, "  +                                 "could not resolve client package "  + callingPackage);                     }                     sInfo = new  ServiceInfo (sInfo);                     sInfo.applicationInfo = new  ApplicationInfo (sInfo.applicationInfo);                     sInfo.applicationInfo.packageName = aInfo.packageName;                     sInfo.applicationInfo.uid = aInfo.uid;                                                               name = new  ComponentName (aInfo.packageName, name.getClassName());                     service.setComponent(name);                 } else  {                     throw  new  SecurityException ("BIND_EXTERNAL_SERVICE required for "  +                             name);                 }             } else  if  (isBindExternal) {                 throw  new  SecurityException ("BIND_EXTERNAL_SERVICE failed, "  + name +                         " is not an externalService" );             }                          if  (userId > 0 ) {                 if  (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,                         sInfo.name, sInfo.flags)                         && mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) {                     userId = 0 ;                     smap = getServiceMap(0 );                 }                 sInfo = new  ServiceInfo (sInfo);                 sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);             }                                       r = smap.mServicesByName.get(name);             if  (r == null  && createIfNeeded) {                 Intent.FilterComparison  filter                          =  new  Intent .FilterComparison(service.cloneFilter());                                                           ServiceRestarter  res  =  new  ServiceRestarter ();                 BatteryStatsImpl.Uid.Pkg.Serv  ss  =  null ;                 BatteryStatsImpl  stats  =  mAm.mBatteryStatsService.getActiveStatistics();                 synchronized  (stats) {                     ss = stats.getServiceStatsLocked(                             sInfo.applicationInfo.uid, sInfo.packageName,                             sInfo.name);                 }                                                    r = new  ServiceRecord (mAm, ss, name, filter, sInfo, callingFromFg, res);                 res.setService(r);                                                   smap.mServicesByName.put(name, r);                 smap.mServicesByIntent.put(filter, r);                                  for  (int  i=mPendingServices.size()-1 ; i>=0 ; i--) {                     ServiceRecord  pr  =  mPendingServices.get(i);                     if  (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid                             && pr.name.equals(name)) {                         mPendingServices.remove(i);                     }                 }             }         } catch  (RemoteException ex) {                      }     }          if  (r != null ) {         if  (mAm.checkComponentPermission(r.permission,                 callingPid, callingUid, r.appInfo.uid, r.exported)                 != PackageManager.PERMISSION_GRANTED) {              if  (!r.exported) {                 Slog.w(TAG, "Permission Denial: Accessing service "  + r.name                         + " from pid="  + callingPid                         + ", uid="  + callingUid                         + " that is not exported from uid "  + r.appInfo.uid);                                                   return  new  ServiceLookupResult (null , "not exported from uid "                          + r.appInfo.uid);             }             Slog.w(TAG, "Permission Denial: Accessing service "  + r.name                     + " from pid="  + callingPid                     + ", uid="  + callingUid                     + " requires "  + r.permission);                          return  new  ServiceLookupResult (null , r.permission);         } else  if  (r.permission != null  && callingPackage != null ) {             final  int  opCode  =  AppOpsManager.permissionToOpCode(r.permission);             if  (opCode != AppOpsManager.OP_NONE && mAm.mAppOpsService.noteOperation(                     opCode, callingUid, callingPackage) != AppOpsManager.MODE_ALLOWED) {                                      Slog.w(TAG, "Appop Denial: Accessing service "  + r.name                         + " from pid="  + callingPid                         + ", uid="  + callingUid                         + " requires appop "  + AppOpsManager.opToName(opCode));                                                           return  null ;             }         }         if  (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,                 resolvedType, r.appInfo)) {                          return  null ;         }                           return  new  ServiceLookupResult (r, null );     }     return  null ; } 
 
这个方法的最终目的是返回要启动的服务的信息封装对象 ServiceLookupResult!
2.3 ActiveServices.stopServiceLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 private  void  stopServiceLocked (ServiceRecord service)  {              if  (service.delayed) {         if  (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Delaying stop of pending: "  + service);                           service.delayedStop = true ;         return ;     }     synchronized  (service.stats.getBatteryStats()) {         service.stats.stopRunningLocked();     }               service.startRequested = false ;     if  (service.tracker != null ) {                           service.tracker.setStarted(false , mAm.mProcessStats.getMemFactorLocked(),                 SystemClock.uptimeMillis());     }               service.callStart = false ;               bringDownServiceIfNeededLocked(service, false , false ); } 
 
2.4 ActiveServices.bringDownServiceIfNeededLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 private  final  void  bringDownServiceIfNeededLocked (ServiceRecord r, boolean  knowConn,         boolean  hasConn)  {              if  (isServiceNeeded(r, knowConn, hasConn)) {         return ;     }          if  (mPendingServices.contains(r)) {         return ;     }          bringDownServiceLocked(r); } 
 
如果这个服务仍然被需要,或者服务所在的进程正在启动,这两种情况下,不能停止服务!
2.4.1 ActiveServices.isServiceNeeded 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 private  final  boolean  isServiceNeeded (ServiceRecord r, boolean  knowConn, boolean  hasConn)  {    if  (r.startRequested) {          return  true ;     }          if  (!knowConn) {         hasConn = r.hasAutoCreateConnections();     }     if  (hasConn) {         return  true ;     }     return  false ; } 
 
判断一个服务是否仍被需要,有两种情况:
服务已经被请求启动,stopService 前面会被置为 false; 
服务被应用通过自动创建的方式绑定,即 bindService 时,flags 为 Context.BIND_AUTO_CREATE; 
 
继续来看!
2.5 ActiveServices.bringDownServiceLocked 我们来看看 bringDownServiceLocked 方法做了什么:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 private  final  void  bringDownServiceLocked (ServiceRecord r)  {                   for  (int  conni=r.connections.size()-1 ; conni>=0 ; conni--) {         ArrayList<ConnectionRecord> c = r.connections.valueAt(conni);         for  (int  i=0 ; i<c.size(); i++) {             ConnectionRecord  cr  =  c.get(i);                                       cr.serviceDead = true ;             try  {                                                                    cr.conn.connected(r.name, null );                              } catch  (Exception e) {                 Slog.w(TAG, "Failure disconnecting service "  + r.name +                       " to connection "  + c.get(i).conn.asBinder() +                       " (in "  + c.get(i).binding.client.processName + ")" , e);             }         }     }          if  (r.app != null  && r.app.thread != null ) {         for  (int  i=r.bindings.size()-1 ; i>=0 ; i--) {             IntentBindRecord  ibr  =  r.bindings.valueAt(i);                          if  (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing down binding "  + ibr                     + ": hasBound="  + ibr.hasBound);                                  if  (ibr.hasBound) {                 try  {                                                               bumpServiceExecutingLocked(r, false , "bring down unbind" );                     mAm.updateOomAdjLocked(r.app);                                                               ibr.hasBound = false ;                                                                                    r.app.thread.scheduleUnbindService(r,                             ibr.intent.getIntent());                 } catch  (Exception e) {                     Slog.w(TAG, "Exception when unbinding service "                              + r.shortName, e);                     serviceProcessGoneLocked(r);                 }             }         }     }     if  (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing down "  + r + " "  + r.intent);               r.destroyTime = SystemClock.uptimeMillis();     if  (LOG_SERVICE_START_STOP) {         EventLogTags.writeAmDestroyService(                 r.userId, System.identityHashCode(r), (r.app != null ) ? r.app.pid : -1 );     }     final  ServiceMap  smap  =  getServiceMap(r.userId);          smap.mServicesByName.remove(r.name);     smap.mServicesByIntent.remove(r.intent);          r.totalRestartCount = 0 ;          unscheduleServiceRestartLocked(r, 0 , true );          for  (int  i=mPendingServices.size()-1 ; i>=0 ; i--) {         if  (mPendingServices.get(i) == r) {             mPendingServices.remove(i);             if  (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Removed pending: "  + r);         }     }               cancelForegroudNotificationLocked(r);          r.isForeground = false ;     r.foregroundId = 0 ;     r.foregroundNoti = null ;          r.clearDeliveredStartsLocked();     r.pendingStarts.clear();     if  (r.app != null ) {         synchronized  (r.stats.getBatteryStats()) {             r.stats.stopLaunchedLocked();         }                           r.app.services.remove(r);         if  (r.whitelistManager) {             updateWhitelistManagerLocked(r.app);         }         if  (r.app.thread != null ) {             updateServiceForegroundLocked(r.app, false );             try  {                                                    bumpServiceExecutingLocked(r, false , "destroy" );                                                   mDestroyingServices.add(r);                 r.destroying = true ;                 mAm.updateOomAdjLocked(r.app);                                                   r.app.thread.scheduleStopService(r);             } catch  (Exception e) {                 Slog.w(TAG, "Exception when destroying service "                          + r.shortName, e);                 serviceProcessGoneLocked(r);             }         } else  {             if  (DEBUG_SERVICE) Slog.v(                 TAG_SERVICE, "Removed service that has no process: "  + r);         }     } else  {         if  (DEBUG_SERVICE) Slog.v(             TAG_SERVICE, "Removed service that is not running: "  + r);     }          if  (r.bindings.size() > 0 ) {         r.bindings.clear();     }          if  (r.restarter instanceof  ServiceRestarter) {        ((ServiceRestarter)r.restarter).setService(null );     }     int  memFactor  =  mAm.mProcessStats.getMemFactorLocked();     long  now  =  SystemClock.uptimeMillis();     if  (r.tracker != null ) {         r.tracker.setStarted(false , memFactor, now);         r.tracker.setBound(false , memFactor, now);         if  (r.executeNesting == 0 ) {             r.tracker.clearCurrentOwner(r, false );             r.tracker = null ;         }     }     smap.ensureNotStartingBackground(r); } 
 
这段代码很简单,主要逻辑如下:
首先进入绑定服务的应用进程,回调 ServiceConnection 的 onServiceDisconnected 方法,取消所有进程对该服务的绑定; 
接着,进入服务所在的进程,拉起服务的 onUnbind 方法; 
最后,拉起服务的 onDestroy 方法,销毁服务; 
 
整个过程,还会清空和重置一些关键变量!!
下面我们重点分析一下上面的三个过程!
3 绑定者进程 系统进程会调用 IServiceConnection.Proxy 代理对象的 connected 方法,通过 binder 调用,进入绑定服务的应用进程,这个是异步调用:
1 cr.conn.connected(r.name, null ); 
 
我们去看看!
3.1 InnerConnection.connected 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 private  static  class  InnerConnection  extends  IServiceConnection .Stub {    final  WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;     InnerConnection(LoadedApk.ServiceDispatcher sd) {         mDispatcher = new  WeakReference <LoadedApk.ServiceDispatcher>(sd);     }     public  void  connected (ComponentName name, IBinder service)  throws  RemoteException {         LoadedApk.ServiceDispatcher  sd  =  mDispatcher.get();         if  (sd != null ) {                                   sd.connected(name, service);         }     } } 
 
继续来看:
3.2 ServiceDispatcher.connected 1 2 3 4 5 6 7 8 9 public  void  connected (ComponentName name, IBinder service)  {    if  (mActivityThread != null ) {         mActivityThread.post(new  RunConnection (name, service, 0 ));     } else  {         doConnected(name, service);     } } 
 
看过 bindService 一文的朋友,应该知道,最后都会调用 doConnected 方法:
3.3 ServiceDispatcher.doConnected 参数 service 这里为 null!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 public  void  doConnected (ComponentName name, IBinder service)  {         ServiceDispatcher.ConnectionInfo old;     ServiceDispatcher.ConnectionInfo info;     synchronized  (this ) {                  if  (mForgotten) {             return ;         }                           old = mActiveConnections.get(name);         if  (old != null  && old.binder == service) {              return ;         }         if  (service != null ) {                          info = new  ConnectionInfo ();             info.binder = service;             info.deathMonitor = new  DeathMonitor (name, service);             try  {                 service.linkToDeath(info.deathMonitor, 0 );                 mActiveConnections.put(name, info);             } catch  (RemoteException e) {                                                   mActiveConnections.remove(name);                 return ;             }         } else  {                          mActiveConnections.remove(name);         }                  if  (old != null ) {             old.binder.unlinkToDeath(old.deathMonitor, 0 );         }     }          if  (old != null ) {                       mConnection.onServiceDisconnected(name);     }          if  (service != null ) {         mConnection.onServiceConnected(name, service);     } } 
 这里,最后会进入应用的 ServiceConnection 对象!1 2 3 4 5 6 private  ServiceConnection  mConnection  =  new  ServiceConnection () {    @Override      public  void  onServiceDisconnected (ComponentName name)  {          } } 
 注意,onServiceDisconnected 方法是非阻塞的,即,系统进程不会等 onServiceDisconnected 执行完才继续执行!!
4 服务所在进程 我们先回到系统进程 bringDownServiceLocked 方法中:1 2 3 4 5 6 7 8 r.app.thread.scheduleUnbindService(r,         ibr.intent.getIntent());          ... ... ... ... r.app.thread.scheduleStopService(r); 
 这两个方法,都通过 ApplicationThreadProxy 对象进行 bind 通信,我们下面来逐个分析:
4.1 ApplicationThread.scheduleUnbindService 参数 IBinder token 就是 ServiceRecord 对象!
1 2 3 4 5 6 7 8 9 10 11 12 13 public  final  void  scheduleUnbindService (IBinder token, Intent intent)         throws  RemoteException {     Parcel  data  =  Parcel.obtain();     data.writeInterfaceToken(IApplicationThread.descriptor);     data.writeStrongBinder(token);     intent.writeToParcel(data, 0 );               mRemote.transact(SCHEDULE_UNBIND_SERVICE_TRANSACTION, data, null , IBinder.FLAG_ONEWAY);     data.recycle(); } 
 
可以看出 scheduleUnbindService  方法的 binder 通信是 IBinder.FLAG_ONEWAY  方式!
4.2 ApplicationThreadP.scheduleStopService 参数 IBinder token 就是 ServiceRecord 对象!
1 2 3 4 5 6 7 8 9 10 11 12 public  final  void  scheduleStopService (IBinder token)         throws  RemoteException {     Parcel  data  =  Parcel.obtain();     data.writeInterfaceToken(IApplicationThread.descriptor);     data.writeStrongBinder(token);               mRemote.transact(SCHEDULE_STOP_SERVICE_TRANSACTION, data, null , IBinder.FLAG_ONEWAY);     data.recycle(); } 
 
可以看出 scheduleStopService  方法的 binder 通信是 IBinder.FLAG_ONEWAY  方式!
下面是真正进入了应用程序进程 !
4.3 ApplicationThreadN.onTransact 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 case  SCHEDULE_UNBIND_SERVICE_TRANSACTION: {    data.enforceInterface(IApplicationThread.descriptor);     IBinder  token  =  data.readStrongBinder();     Intent  intent  =  Intent.CREATOR.createFromParcel(data);               scheduleUnbindService(token, intent);     return  true ; } case  SCHEDULE_STOP_SERVICE_TRANSACTION:{     data.enforceInterface(IApplicationThread.descriptor);     IBinder  token  =  data.readStrongBinder();               scheduleStopService(token);     return  true ; } 
 
4.4 ApplicationThread 接着,进入 ApplicationThread!!
4.4.1 ApplicationThread.scheduleUnbindService 1 2 3 4 5 6 7 8 9 10 public  final  void  scheduleUnbindService (IBinder token, Intent intent)  {    BindServiceData  s  =  new  BindServiceData ();               s.token = token;     s.intent = intent;          sendMessage(H.UNBIND_SERVICE, s); } 
 
4.4.2 ApplicationThread.scheduleStopService 1 2 3 4 5 public  final  void  scheduleStopService (IBinder token)  {         sendMessage(H.STOP_SERVICE, token); } 
 
4.5 ActivityThread.H 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 private  class  H  extends  Handler  {    public  void  handleMessage (Message msg)  {             case  UNBIND_SERVICE:                 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind" );                                  handleUnbindService((BindServiceData)msg.obj);                                  Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                 break ;             case  STOP_SERVICE:                 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop" );                                  handleStopService((IBinder)msg.obj);                 maybeSnapshot();                                  Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                 break ;             } } 
 
这里很简单,我们继续看:
4.5.1 ActivityThread.handleUnbindService 首先会拉起 Serivce 的 onUnbind 方法!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 private  void  handleUnbindService (BindServiceData data)  {         Service  s  =  mServices.get(data.token);     if  (s != null ) {         try  {             data.intent.setExtrasClassLoader(s.getClassLoader());             data.intent.prepareToEnterProcess();                                       boolean  doRebind  =  s.onUnbind(data.intent);             try  {                 if  (doRebind) {                                                           ActivityManagerNative.getDefault().unbindFinished(                             data.token, data.intent, doRebind);                 } else  {                                                           ActivityManagerNative.getDefault().serviceDoneExecuting(                             data.token, SERVICE_DONE_EXECUTING_ANON, 0 , 0 );                 }             } catch  (RemoteException ex) {                 throw  ex.rethrowFromSystemServer();             }         } catch  (Exception e) {             if  (!mInstrumentation.onException(s, e)) {                 throw  new  RuntimeException (                         "Unable to unbind to service "  + s                         + " with "  + data.intent + ": "  + e.toString(), e);             }         }     } } 
 
如果 onUnbind 方法返回 true,并且服务被解绑后没有被销毁,下次被绑定时,会拉起 onRebind 方法!
4.5.2 ActivityThread.handleStopService 最后,拉起 Serivce 的 onDestroy 方法!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 private  void  handleStopService (IBinder token)  {              Service  s  =  mServices.remove(token);     if  (s != null ) {         try  {             if  (localLOGV) Slog.v(TAG, "Destroying service "  + s);                                       s.onDestroy();             Context  context  =  s.getBaseContext();             if  (context instanceof  ContextImpl) {                 final  String  who  =  s.getClassName();                                                   ((ContextImpl) context).scheduleFinalCleanup(who, "Service" );             }             QueuedWork.waitToFinish();             try  {                                  ActivityManagerNative.getDefault().serviceDoneExecuting(                         token, SERVICE_DONE_EXECUTING_STOP, 0 , 0 );             } catch  (RemoteException e) {                 throw  e.rethrowFromSystemServer();             }         } catch  (Exception e) {             if  (!mInstrumentation.onException(s, e)) {                 throw  new  RuntimeException (                         "Unable to stop service "  + s                         + ": "  + e.toString(), e);             }             Slog.i(TAG, "handleStopService: exception for "  + token, e);         }     } else  {         Slog.i(TAG, "handleStopService: token="  + token + " not found." );     }      } 
 
这里逻辑很清楚,我们继续来看,接下来,调用 ActivityManagerP 相关的方法!
4.6 ActivityManagerProxy 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public  void  unbindFinished (IBinder token, Intent intent, boolean  doRebind)         throws  RemoteException {              Parcel  data  =  Parcel.obtain();     Parcel  reply  =  Parcel.obtain();     data.writeInterfaceToken(IActivityManager.descriptor);     data.writeStrongBinder(token);     intent.writeToParcel(data, 0 );     data.writeInt(doRebind ? 1  : 0 );               mRemote.transact(UNBIND_FINISHED_TRANSACTION, data, reply, 0 );     reply.readException();     data.recycle();     reply.recycle(); } public  void  serviceDoneExecuting (IBinder token, int  type, int  startId,         int  res)  throws  RemoteException {             Parcel  data  =  Parcel.obtain();     Parcel  reply  =  Parcel.obtain();     data.writeInterfaceToken(IActivityManager.descriptor);     data.writeStrongBinder(token);     data.writeInt(type);     data.writeInt(startId);     data.writeInt(res);               mRemote.transact(SERVICE_DONE_EXECUTING_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);     reply.readException();     data.recycle();     reply.recycle(); } 
 
发送了 UNBIND_FINISHED_TRANSACTION  和 SERVICE_DONE_EXECUTING_TRANSACTION  消息!
unbindFinished 的 binder 通信是同步的,serviceDoneExecuting 的 binder 通信是异步的!
5 系统进程 首先会进入 ActivityManagerNative 的 onTransact 方法中:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 case  UNBIND_FINISHED_TRANSACTION: {    data.enforceInterface(IActivityManager.descriptor);     IBinder  token  =  data.readStrongBinder();     Intent  intent  =  Intent.CREATOR.createFromParcel(data);     boolean  doRebind  =  data.readInt() != 0 ;               unbindFinished(token, intent, doRebind);     reply.writeNoException();     return  true ; } case  SERVICE_DONE_EXECUTING_TRANSACTION: {    data.enforceInterface(IActivityManager.descriptor);     IBinder  token  =  data.readStrongBinder();     int  type  =  data.readInt();     int  startId  =  data.readInt();     int  res  =  data.readInt();               serviceDoneExecuting(token, type, startId, res);     reply.writeNoException();     return  true ; } 
 接下来,进入 AMS!
5.1 ActivityManagerS.unbindFinished 1 2 3 4 5 6 7 8 9 10 11 12 13 public  void  unbindFinished (IBinder token, Intent intent, boolean  doRebind)  {              if  (intent != null  && intent.hasFileDescriptors() == true ) {         throw  new  IllegalArgumentException ("File descriptors passed in Intent" );     }     synchronized (this ) {                           mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);     } } 
 
5.1.1 ActiveServices.unbindFinishedLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 void  unbindFinishedLocked (ServiceRecord r, Intent intent, boolean  doRebind)  {    final  long  origId  =  Binder.clearCallingIdentity();     try  {         if  (r != null ) {             Intent.FilterComparison  filter                      =  new  Intent .FilterComparison(intent);                                       IntentBindRecord  b  =  r.bindings.get(filter);             if  (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "unbindFinished in "  + r                     + " at "  + b + ": apps="                      + (b != null  ? b.apps.size() : 0 ));                                       boolean  inDestroying  =  mDestroyingServices.contains(r);                                       if  (b != null ) {                 if  (b.apps.size() > 0  && !inDestroying) {                                                               boolean  inFg  =  false ;                     for  (int  i=b.apps.size()-1 ; i>=0 ; i--) {                         ProcessRecord  client  =  b.apps.valueAt(i).client;                         if  (client != null  && client.setSchedGroup                                 != ProcessList.SCHED_GROUP_BACKGROUND) {                             inFg = true ;                             break ;                         }                     }                     try  {                         requestServiceBindingLocked(r, b, inFg, true );                     } catch  (TransactionTooLargeException e) {                                              }                 } else  {                                          b.doRebind = true ;                 }             }                                       serviceDoneExecutingLocked(r, inDestroying, false );         }     } finally  {         Binder.restoreCallingIdentity(origId);     } } 
 
接着来看!
5.1.2 ActiveServices.serviceDoneExecutingLocked 参数传递:
boolean inDestroying:传入 false; 
boolean finishing:传入 false; 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 private  void  serviceDoneExecutingLocked (ServiceRecord r, boolean  inDestroying,         boolean  finishing)  {    if  (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "<<< DONE EXECUTING "  + r             + ": nesting="  + r.executeNesting             + ", inDestroying="  + inDestroying + ", app="  + r.app);     else  if  (DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING,             "<<< DONE EXECUTING "  + r.shortName);     r.executeNesting--;     if  (r.executeNesting <= 0 ) {         if  (r.app != null ) {             if  (DEBUG_SERVICE) Slog.v(TAG_SERVICE,                     "Nesting at 0 of "  + r.shortName);                                       r.app.execServicesFg = false ;             r.app.executingServices.remove(r);             if  (r.app.executingServices.size() == 0 ) {                 if  (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING,                         "No more executingServices of "  + r.shortName);                                                   mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);             } else  if  (r.executeFg) {                                  for  (int  i=r.app.executingServices.size()-1 ; i>=0 ; i--) {                     if  (r.app.executingServices.valueAt(i).executeFg) {                         r.app.execServicesFg = true ;                         break ;                     }                 }             }             if  (inDestroying) {                  if  (DEBUG_SERVICE) Slog.v(TAG_SERVICE,                         "doneExecuting remove destroying "  + r);                 mDestroyingServices.remove(r);                 r.bindings.clear();             }                                       mAm.updateOomAdjLocked(r.app);         }                   r.executeFg = false ;         if  (r.tracker != null ) {             r.tracker.setExecuting(false , mAm.mProcessStats.getMemFactorLocked(),                     SystemClock.uptimeMillis());             if  (finishing) {                 r.tracker.clearCurrentOwner(r, false );                 r.tracker = null ;             }         }         if  (finishing) {              if  (r.app != null  && !r.app.persistent) {                 r.app.services.remove(r);                 if  (r.whitelistManager) {                     updateWhitelistManagerLocked(r.app);                 }             }             r.app = null ;         }     } } 
 
这里就不再详细说了!!
5.2 ActivityManagerS.serviceDoneExecuting 对于拉起 onDestroy 方法,最后会调用1 2 3 4 5 6 7 8 9 10 11 public  void  serviceDoneExecuting (IBinder token, int  type, int  startId, int  res)  {    synchronized (this ) {         if  (!(token instanceof  ServiceRecord)) {             Slog.e(TAG, "serviceDoneExecuting: Invalid service token="  + token);             throw  new  IllegalArgumentException ("Invalid service token" );         }                           mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);     } } 
 接着,进入 ActiveServices!
5.2.1 ActiveServices.serviceDoneExecutingLocked 根据参数传递:
int type :传入 ActivityThread.SERVICE_DONE_EXECUTING_STOP; 
int startId :传入 0; 
int res :传入 0; 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 void  serviceDoneExecutingLocked (ServiceRecord r, int  type, int  startId, int  res)  {              boolean  inDestroying  =  mDestroyingServices.contains(r);     if  (r != null ) {         if  (type == ActivityThread.SERVICE_DONE_EXECUTING_START) {                          ... ... ...                       } else  if  (type == ActivityThread.SERVICE_DONE_EXECUTING_STOP) {                                                    if  (!inDestroying) {                                                                                     if  (r.app != null ) {                     Slog.w(TAG, "Service done with onDestroy, but not inDestroying: "                              + r + ", app="  + r.app);                 }             } else  if  (r.executeNesting != 1 ) {                 Slog.w(TAG, "Service done with onDestroy, but executeNesting="                          + r.executeNesting + ": "  + r);                                  r.executeNesting = 1 ;             }         }         final  long  origId  =  Binder.clearCallingIdentity();                           serviceDoneExecutingLocked(r, inDestroying, inDestroying);         Binder.restoreCallingIdentity(origId);     } else  {         Slog.w(TAG, "Done executing unknown service from pid "                  + Binder.getCallingPid());     } } 
 
5.2.2 ActiveServices.serviceDoneExecutingLocked 参数传递:
boolean inDestroying:传入 true; 
boolean finishing:传入 true; 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 private  void  serviceDoneExecutingLocked (ServiceRecord r, boolean  inDestroying,         boolean  finishing)  {    if  (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "<<< DONE EXECUTING "  + r             + ": nesting="  + r.executeNesting             + ", inDestroying="  + inDestroying + ", app="  + r.app);     else  if  (DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING,             "<<< DONE EXECUTING "  + r.shortName);     r.executeNesting--;     if  (r.executeNesting <= 0 ) {         if  (r.app != null ) {             if  (DEBUG_SERVICE) Slog.v(TAG_SERVICE,                     "Nesting at 0 of "  + r.shortName);                                       r.app.execServicesFg = false ;             r.app.executingServices.remove(r);             if  (r.app.executingServices.size() == 0 ) {                 if  (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING,                         "No more executingServices of "  + r.shortName);                                                   mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);             } else  if  (r.executeFg) {                                  for  (int  i=r.app.executingServices.size()-1 ; i>=0 ; i--) {                     if  (r.app.executingServices.valueAt(i).executeFg) {                         r.app.execServicesFg = true ;                         break ;                     }                 }             }             if  (inDestroying) {                  if  (DEBUG_SERVICE) Slog.v(TAG_SERVICE,                         "doneExecuting remove destroying "  + r);                                                           mDestroyingServices.remove(r);                                                   r.bindings.clear();             }                                       mAm.updateOomAdjLocked(r.app);         }                   r.executeFg = false ;         if  (r.tracker != null ) {             r.tracker.setExecuting(false , mAm.mProcessStats.getMemFactorLocked(),                     SystemClock.uptimeMillis());                                               if  (finishing) {                 r.tracker.clearCurrentOwner(r, false );                 r.tracker = null ;             }         }         if  (finishing) {              if  (r.app != null  && !r.app.persistent) {                                               r.app.services.remove(r);                 if  (r.whitelistManager) {                     updateWhitelistManagerLocked(r.app);                 }             }             r.app = null ;         }     } } 
 
到这里,stopService 的整个过程,就分析完了!!
6 总结 我们来回顾一下,整个 stopService 的过程,都遇到了那些重要的数据结构!