在前面文章我们分析了四大组件中的两个:Broadcast和Activity,这章我们分析四大组件中的服务(Service)的启动过程。Service的启动方式有两种:一种是startService,一种是bindService;第一种通常是开启一个服务执行后台任务,不进行通信,第二章通过是启动服务进行通信。下面我们就根据这两种启动方式来讲Service的启动流程以及unbindService和stopService流程。
Service启动流程-startService 首先来看启动流程时序图:
Step0.ContextImpl.startService 1 2 3 4 5 @Override public ComponentName startService (Intent service) { warnIfCallingFromSystemProcess(); return startServiceCommon(service, mUser); }
调用当前类中的startServiceCommon方法。
Step1.ContextImpl.startServiceCommon 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 private ComponentName startServiceCommon (Intent service, UserHandle user) { try { validateServiceIntent(service); service.prepareToLeaveProcess(this ); ComponentName cn = ActivityManagerNative.getDefault().startService( mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded( getContentResolver()), getOpPackageName(), user.getIdentifier()); ... return cn; } catch (RemoteException e) { ... } }
首先验证Intent中传递的组件名是否为空,为什么判断下面我们介绍,接着通过代理对象ActivityManagerProxy,通过Binder调用AMS(ActivityManagerService)中的对应方法startService。我们先看包名验证。
Step2.ContextImpl.validateServiceIntent 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 )); } } }
这里给出了如果系统在Android5.0及以上版本,启动服务必须为显式启动,否则抛出异常,这个情况我们在刚开始在高于5.0系统都会遇到过,限制就在这里,所以,5.0及以上系统必须用显式的方式启动服务。
3.AMP.startService 1 2 3 4 5 6 7 8 9 public ComponentName startService (IApplicationThread caller, Intent service, String resolvedType, String callingPackage, int userId) throws RemoteException { ... mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0 ); ... return res; }
看过前面文章的对这一段代码应该很熟悉了,这个就是通过Binder调用AMS中对应方法的。所以我们直接看AMS。
4.AMS.startService 1 2 3 4 5 6 7 8 9 10 11 12 13 public ComponentName startService (IApplicationThread caller, Intent service, String resolvedType, String callingPackage, int userId) throws TransactionTooLargeException { ... synchronized (this ) { ... ComponentName res = mServices.startServiceLocked(caller, service, resolvedType, callingPid, callingUid, callingPackage, userId); Binder.restoreCallingIdentity(origId); return res; } }
这里的mServices是ActiveServices,因此调用的是ActiveServices中的startServiceLocked方法。
5.ActiveServices.startServiceLocked 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 ComponentName startServiceLocked (IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid, String callingPackage, final int userId) throws TransactionTooLargeException { ... ServiceLookupResult res = retrieveServiceLocked(service, resolvedType, callingPackage, callingPid, callingUid, userId, true , callerFg, false ); ... ServiceRecord r = res.record; ... r.pendingStarts.add(new ServiceRecord .StartItem(r, false , r.makeNextStartId(), service, neededGrants)); final ServiceMap smap = getServiceMap(r.userId); boolean addToStarting = false ; if (!callerFg && r.app == null && mAm.mUserController.hasStartedUserState(r.userId)) { ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false ); ... } else if (DEBUG_DELAYED_STARTS) { ... } return startServiceInnerLocked(smap, service, r, callerFg, addToStarting); }
这里做的主要是启动服务前的准备工作,首先是解析Intent携带的参数,并将这些内容保存在用来描述Service的ServiceRecord对象中保存起来,并将该对象放到等待启动服务的列表中。然后调用startServiceInnerLocked启动服务。在上面调用retrieveServiceLocked函数解析的过程中先去判断AMS中是否存在参数为service对应的ServiceRecord对象,如果存在说明已经启动过该服务,如果不存在,说明是第一次启动该服务。
8.ActiveServices.startServiceInnerLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 ComponentName startServiceInnerLocked (ServiceMap smap, Intent service, ServiceRecord r, boolean callerFg, boolean addToStarting) throws TransactionTooLargeException { ServiceState stracker = r.getTracker(); ... r.callStart = false ; ... String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false , false ); ... return r.name; }
这里比较简单主要是调用bringUpServiceLocked唤起服务。
Step9.ActiveServices.bringUpServiceLocked 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 private String bringUpServiceLocked (ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting, boolean permissionsReviewRequired) throws TransactionTooLargeException { if (r.app != null && r.app.thread != null ) { sendServiceArgsLocked(r, execInFg, false ); return null ; } ... if (!mAm.mUserController.hasStartedUserState(r.userId)) { ... bringDownServiceLocked(r); return msg; } ... final boolean isolated = (r.serviceInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) != 0 ; final String procName = r.processName; ProcessRecord app; if (!isolated) { app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false ); if (app != null && app.thread != null ) { try { ... realStartServiceLocked(r, app, execInFg); return null ; } catch (TransactionTooLargeException e) { ... } } } else { ... } if (app == null && !permissionsReviewRequired) { if ((app = mAm.startProcessLocked(procName, r.appInfo, true , intentFlags, "service" , r.name, false , isolated, false )) == null ) { ... bringDownServiceLocked(r); return msg; } ... } ... if (r.delayedStop) { r.delayedStop = false ; if (r.startRequested) { stopServiceLocked(r); } } return null ; }
这里是启动服务最重要的部分,根据不同的情况进行不同的处理。首先是判断服务所在进程是否存在,如果存在调用sendServiceArgsLocked方法,最终根据条件,如果服务存在调用服务的onStartCommand方法;然后判断被启动服务的用户是否已经被启动,如果没有则停止服务,也就是调用bringDownServiceLocked方法,最终调用服务的onDestroy方法;然后判断非独立进程的服务,如果进程存在并且服务未启动的开始正式启动服务,调用realStartServiceLocked方法,最终调用onCreate方法;然后判断如果进程不存在,要启动进程,并且在app启动后启动服务,这里会调用启动失败,停止启动,因为进程启动后会启动该服务,这个过程在前面我们讲过,这里不再分析这种情况。最后是如果是延迟停止的服务这里直接停止该服务。下面我们按顺序分析这几种情况。
Step10.ActiveServices.sendServiceArgsLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 private final void sendServiceArgsLocked (ServiceRecord r, boolean execInFg, boolean oomAdjusted) throws TransactionTooLargeException { final int N = r.pendingStarts.size(); if (N == 0 ) { return ; } while (r.pendingStarts.size() > 0 ) { ... try { .. bumpServiceExecutingLocked(r, execInFg, "start" ); ... r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent); } catch (TransactionTooLargeException e) { ... } } }
上面Step5提到启动的服务都要先放到等待启动服务列表中,因此这里先判断服务列表是否存在要启动的服务,如果不存在则不再继续执行,如果存在,循环启动服务,这里调用scheduleServiceArgs方法,其实在前面分析了很多遍,最终会发送消息ActivityThread中的Handler中的handleMessage中进行处理,然后调用ActivityThread中的handleServiceArgs方法。
Step13.ActivityThread.handleServiceArgs 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 private void handleServiceArgs (ServiceArgsData data) { Service s = mServices.get(data.token); if (s != null ) { try { ... if (!data.taskRemoved) { res = s.onStartCommand(data.args, data.flags, data.startId); } else { s.onTaskRemoved(data.args); res = Service.START_TASK_REMOVED_COMPLETE; } ... } catch (Exception e) { ... } } }
根据Service对应的token去缓存中获取服务,如果有该服务那么调用服务的onStartCommand方法,如果不存在那么就要继续往下走创建服务。
Step15.ActiveServices.bringDownServiceLocked 这个方法主要是处理停止服务的方法,里面主要是断开连接,解除绑定,然后销毁服务,因为这个过程是在服务停止时会调用,所以在后面介绍,这里先不介绍了。
Step16.ActiveServices.realStartServiceLocked 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 private final void realStartServiceLocked (ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { ... boolean created = false ; ... app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), app.repProcState); ... requestServiceBindingsLocked(r, execInFg); ... sendServiceArgsLocked(r, execInFg, true ); ... }
启动服务调用三个方法,首先是通过app.thread.scheduleCreateService方法调用onCreate方法,然后通过requestServiceBindingsLocked方法调用Service.onBind方法,然后通过sendServiceArgsLocked方法调用Service.onStartCommand方法,其中最后一个方法我们分析过了,所以我们只分析前两个。第一很简单了,最终调用ActivityThread中的handleCreateService方法。
Step18.ActivityThread.handleCreateService 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 private void handleCreateService (CreateServiceData data) { ... LoadedApk packageInfo = getPackageInfoNoCheck( data.info.applicationInfo, data.compatInfo); Service service = null ; ... java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = (Service) cl.loadClass(data.info.name).newInstance(); ... ContextImpl context = ContextImpl.createAppContext(this , packageInfo); context.setOuterContext(service); Application app = packageInfo.makeApplication(false , mInstrumentation); service.attach(context, this , data.info.name, data.token, app, ActivityManagerNative.getDefault()); service.onCreate(); mServices.put(data.token, service); ... } catch (Exception e) { ... } }
首先获取LoadedApk对象,然后通过类加载器加载Service类,初始化Context,获取对应的Application,如果存在直接返回,如果该应用还没启动则直接创建该Application,然后通过Service的attach方法将对应的信息放置到Service中,这里面就包含ActivityThread,因此我们在Step9中可以通过这个来判断Service是不是被启动了,然后调用onCreate方法,创建完成后,将该服务以token为键,Service为值放入到缓存中,这样我们前面获取的时候就只从这里获取的,因此如果服务启动了换粗就会存在,否则不存在。下面我们分析onBind方法。
Step20.ActiveServices.requestServiceBindingsLocked 1 2 3 4 5 6 7 8 9 10 11 12 private final void requestServiceBindingsLocked (ServiceRecord r, boolean execInFg) throws TransactionTooLargeException { for (int i = r.bindings.size() - 1 ; i >= 0 ; i--) { IntentBindRecord ibr = r.bindings.valueAt(i); if (!requestServiceBindingLocked(r, ibr, execInFg, false )) { break ; } } }
for循环调用onBind。
Step21.ActiveServices.requestServiceBindingLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 private final boolean requestServiceBindingLocked (ServiceRecord r, IntentBindRecord i, boolean execInFg, boolean rebind) throws TransactionTooLargeException { ... if ((!i.requested || rebind) && i.apps.size() > 0 ) { try { ... r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind, r.app.repProcState); if (!rebind) { i.requested = true ; } ... } } return true ; }
这里通过调用r.app.thread.scheduleBindService方法,最终调用到ActivityThread中的handleBindService方法。
Step23.ActivityThread.handleBindService 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 private void handleBindService (BindServiceData data) { Service s = mServices.get(data.token); if (s != null ) { try { ... if (!data.rebind) { IBinder binder = s.onBind(data.intent); ... } else { s.onRebind(data.intent); ... } ... } catch (Exception e) { ... } } }
现获取服务,然后判断是再次绑定还是首次绑定,如果是首次绑定调用Service.onBind方法,如果是再次绑定调用Service.onRebind方法。到这里服务的启动就完成了,其他一些操作就不分析了。下面我们先分析另外一个启动流程bindService,最后分析停止服务流程。
Service启动流程-bindService 首先来看绑定流程时序图:
Step1.ContextImpl.bindService 1 2 3 4 5 6 public boolean bindService (Intent service, ServiceConnection conn, int flags) { warnIfCallingFromSystemProcess(); return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), Process.myUserHandle()); }
这里是绑定服务的入口位置,调用bindServiceCommon方法。
Step2.ContextImpl.bindServiceCommon 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 private boolean bindServiceCommon (Intent service, ServiceConnection conn, int flags, Handler handler, UserHandle user) { IServiceConnection sd; ... if (mPackageInfo != null ) { sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags); } else { ... } ... try { IBinder token = getActivityToken(); ... int res = ActivityManagerNative.getDefault().bindService( mMainThread.getApplicationThread(), getActivityToken(), service, service.resolveTypeIfNeeded(getContentResolver()), sd, flags, getOpPackageName(), user.getIdentifier()); ... return res != 0 ; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }
首先调用LoadedApk中的getServiceDispatcher方法获取实现IServiceConnection接口的Binder对象ServiceDispatcher.InnerConnection。然后调用AMP中的bindService方法,然后通过Binder通信调用AMS中的bindService方法。
Step3.LoadedApk.getServiceDispatcher 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 public final IServiceConnection getServiceDispatcher (ServiceConnection c, Context context, Handler handler, int flags) { synchronized (mServices) { LoadedApk.ServiceDispatcher sd = null ; ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context); if (map != null ) { sd = map.get(c); } if (sd == null ) { sd = new ServiceDispatcher (c, context, handler, flags); if (map == null ) { map = new ArrayMap <ServiceConnection, LoadedApk.ServiceDispatcher>(); mServices.put(context, map); } map.put(c, sd); } else { sd.validate(context, handler); } return sd.getIServiceConnection(); } }
首先根据ServiceConnection取缓存中获取,如果没有要初始化一个ServiceDispatcher对象,然后获取ServiceDispatcher.InnerConnection对象并且返回。
Step6.AMP.bindService 1 2 3 4 5 6 7 8 9 public int bindService (IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags, String callingPackage, int userId) throws RemoteException { ... mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0 ); ... return res; }
这里通过Binder调用AMS中对应的方法。
Step7.AMS.bindService 1 2 3 4 5 6 7 8 9 10 public int bindService (IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags, String callingPackage, int userId) throws TransactionTooLargeException { ... synchronized (this ) { return mServices.bindServiceLocked(caller, token, service, resolvedType, connection, flags, callingPackage, userId); } }
这里调用ActiveServices.bindServiceLocked方法。
Step8.ActiveServices.bindServiceLocked 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 int bindServiceLocked (IApplicationThread caller, IBinder token, Intent service, String resolvedType, final IServiceConnection connection, int flags, String callingPackage, final int userId) throws TransactionTooLargeException { if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "bindService: " + service + " type=" + resolvedType + " conn=" + connection.asBinder() + " flags=0x" + Integer.toHexString(flags)); final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller); ... ActivityRecord activity = null ; if (token != null ) { activity = ActivityRecord.isInStackLocked(token); if (activity == null ) { Slog.w(TAG, "Binding with unknown activity: " + token); return 0 ; } } ... final boolean callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND; final boolean isBindExternal = (flags & Context.BIND_EXTERNAL_SERVICE) != 0 ; ServiceLookupResult res = retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(), Binder.getCallingUid(), userId, true , callerFg, isBindExternal); ... AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); ConnectionRecord c = new ConnectionRecord (b, activity, connection, flags, clientLabel, clientIntent); IBinder binder = connection.asBinder(); ArrayList<ConnectionRecord> clist = s.connections.get(binder); if (clist == null ) { clist = new ArrayList <ConnectionRecord>(); s.connections.put(binder, clist); } clist.add(c); b.connections.add(c); if (activity != null ) { if (activity.connections == null ) { activity.connections = new HashSet <ConnectionRecord>(); } activity.connections.add(c); } ... clist = mServiceConnections.get(binder); if (clist == null ) { clist = new ArrayList <ConnectionRecord>(); mServiceConnections.put(binder, clist); } clist.add(c); if ((flags & Context.BIND_AUTO_CREATE) != 0 ) { s.lastActivity = SystemClock.uptimeMillis(); if (bringUpServiceLocked(s, service.getFlags(), callerFg, false , permissionsReviewRequired) != null ) { return 0 ; } } ... if (s.app != null && b.intent.received) { try { c.conn.connected(s.name, b.intent.binder); } catch (Exception e) { Slog.w(TAG, "Failure sending service " + s.shortName + " to connection " + c.conn.asBinder() + " (in " + c.binding.client.processName + ")" , e); } if (b.intent.apps.size() == 1 && b.intent.doRebind) { requestServiceBindingLocked(s, b.intent, callerFg, true ); } } else if (!b.intent.requested) { requestServiceBindingLocked(s, b.intent, callerFg, false ); } getServiceMap(s.userId).ensureNotStartingBackground(s); } finally { Binder.restoreCallingIdentity(origId); } return 1 ; }
这里代码比较多,所以写的注释也比较多,前面主要是判断是否绑定过该服务,并对InnerConnection进行缓存,放置到各个列表中,让Activity,Service进行联系。最后调用requestServiceBindingLocked方法,这个方法调用两次,一次是首次绑定,一个是重新绑定。
Step9.AMS.requestServiceBindingLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 private final boolean requestServiceBindingLocked (ServiceRecord r, IntentBindRecord i, boolean execInFg, boolean rebind) throws TransactionTooLargeException { ... if ((!i.requested || rebind) && i.apps.size() > 0 ) { try { bumpServiceExecutingLocked(r, execInFg, "bind" ); r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE); r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind, r.app.repProcState); if (!rebind) { i.requested = true ; } i.hasBound = true ; i.doRebind = false ; ... } return true ; }
这里是判断首次绑定还是重新绑定,这两种绑定都会执行绑定步骤,这里有个参数i.requested,代表是否是首次绑定,如果默认值是false,如果不是重新绑定,那么执行完绑定就会设置为true。然后调用thread.scheduleBindServic方法,这个方法讲了很多次了,最终调用ApplicationThread.scheduleBindService方法,然后通过handler调用ActivityThread.handleBindService方法。
Step10.ActivityThread.handleBindService 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 private void handleBindService (BindServiceData data) { Service s = mServices.get(data.token); ... if (!data.rebind) { IBinder binder = s.onBind(data.intent); ActivityManagerNative.getDefault().publishService( data.token, data.intent, binder); } else { s.onRebind(data.intent); ActivityManagerNative.getDefault().serviceDoneExecuting( data.token, SERVICE_DONE_EXECUTING_ANON, 0 , 0 ); } }
这里如果是首次绑定调用onBind方法,否则调用onRebind方法,在首次调用绑定后还有publishService方法,自己看一下,不在详细分析了。这样绑定流程就分析完了,难度不大。下面我们开分析解绑过程。
Service解绑流程-unbindService 首先来看解绑流程时序图:
Step1.ContextImpl.unbindService 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public void unbindService (ServiceConnection conn) { ... if (mPackageInfo != null ) { IServiceConnection sd = mPackageInfo.forgetServiceDispatcher( getOuterContext(), conn); try { ActivityManagerNative.getDefault().unbindService(sd); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } else { throw new RuntimeException ("Not supported in system context" ); } }
IServiceConnection对象的获取我们前面分析过了,这里直接过,然后调用AMP.unbindService方法,最终调用AMS.unbindService方法。
Step3.AMS.unbindService 1 2 3 4 5 public boolean unbindService (IServiceConnection connection) { synchronized (this ) { return mServices.unbindServiceLocked(connection); } }
这里调用ActiveServices.unbindServiceLocked方法。
Step4.ActiveServices.unbindServiceLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 boolean unbindServiceLocked (IServiceConnection connection) { IBinder binder = connection.asBinder(); ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder); ... try { while (clist.size() > 0 ) { ConnectionRecord r = clist.get(0 ); removeConnectionLocked(r, null , null ); if (clist.size() > 0 && clist.get(0 ) == r) { Slog.wtf(TAG, "Connection " + r + " not removed for binder " + binder); clist.remove(0 ); } .... } } finally { Binder.restoreCallingIdentity(origId); } return true ; }
首先从AMS中获取绑定过的列表,如果存在说明绑定过,然后调用removeConnectionLocked移除连接。
Step5.ActiveServices.removeConnectionLocked 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 void removeConnectionLocked ( ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) { IBinder binder = c.conn.asBinder(); AppBindRecord b = c.binding; ServiceRecord s = b.service; ArrayList<ConnectionRecord> clist = s.connections.get(binder); if (clist != null ) { clist.remove(c); if (clist.size() == 0 ) { s.connections.remove(binder); } } b.connections.remove(c); ... clist = mServiceConnections.get(binder); if (clist != null ) { clist.remove(c); if (clist.size() == 0 ) { mServiceConnections.remove(binder); } } mAm.stopAssociationLocked(b.client.uid, b.client.processName, s.appInfo.uid, s.name); if (b.connections.size() == 0 ) { b.intent.apps.remove(b.client); } if (!c.serviceDead) { if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0 && b.intent.hasBound) { try { ... b.intent.doRebind = false ; s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent()); } catch (Exception e) { Slog.w(TAG, "Exception when unbinding service " + s.shortName, e); serviceProcessGoneLocked(s); } } ... } }
在绑定服务的时候进行各种缓存,加入各种列表,那么在接触绑定的时候就有从之前加入的列表中删除,然后执行接触绑定。
Step7.ActivityThread.handleUnbindService 1 2 3 4 5 6 7 8 9 10 11 12 private void handleUnbindService (BindServiceData data) { Service s = mServices.get(data.token); if (s != null ) { try { ... boolean doRebind = s.onUnbind(data.intent); ... } catch (Exception e) { ... } } }
调用Service的onUnbind接触绑定。到这里接触绑定就分析完了,过程比较简单,只是上面的各种列表搞清楚要多看看。最后就剩下了stopService,我们一口气就将它分析完。
Service停止流程-stopService 首先来看停止服务流程时序图:
Step1.ContextImpl.stopSevice 1 2 3 4 5 6 @Override public boolean stopService (Intent service) { warnIfCallingFromSystemProcess(); return stopServiceCommon(service, mUser); }
调用stopServiceCommon停止服务。
Step2.ContextImpl.stopServiceCommon 1 2 3 4 5 6 7 8 9 10 11 12 13 14 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()); ... return res != 0 ; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }
这里最终调用AMS的stopService方法。
Step3.AMS.stopService 1 2 3 4 5 6 7 8 public int stopService (IApplicationThread caller, Intent service, String resolvedType, int userId) { ... synchronized (this ) { return mServices.stopServiceLocked(caller, service, resolvedType, userId); } }
这里就是简单的调用ActiveServices.stopServiceLocked方法。
Step4.ActiveServices.stopServiceLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 int stopServiceLocked (IApplicationThread caller, Intent service, String resolvedType, int userId) { final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller); ... if (r != null ) { ... stopServiceLocked(r.record); ... return -1 ; } return 0 ; }
简单的调用了stopServiceLocked方法。
Step6.ActiveServices.stopServiceLocked 1 2 3 4 private void stopServiceLocked (ServiceRecord service) { ... bringDownServiceIfNeededLocked(service, false , false ); }
我们前面分析过bringUp的是启动服务,因此对应的bringDown的是结束服务。
Step7.ActiveServices.bringDownServiceIfNeededLocked 1 2 3 4 5 6 7 private final void bringDownServiceIfNeededLocked (ServiceRecord r, boolean knowConn, boolean hasConn) { ... bringDownServiceLocked(r); }
这里只是简单的调用了bringDownServiceLocked方法,这个方法我们在服务启动时也遇到过,只是没有分析,我们放到了停止服务的流程中来分析,下面我们看看详细代码。
Step8.ActiveServices.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 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++) { ... cr.conn.connected(r.name, null ); ... } } 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 (ibr.hasBound) { try { ... r.app.thread.scheduleUnbindService(r, ibr.intent.getIntent()); } catch (Exception e) { ... } } } } ... if (r.app != null ) { ... if (r.app.thread != null ) { updateServiceForegroundLocked(r.app, false ); try { ... r.app.thread.scheduleStopService(r); } catch (Exception e) { ... ... }
这里主要有三步,第一步,断开服务连接,这个方法我们前面提到过,可以根据前面提到的去看看如何断开连接的;第二步,如果已经绑定了服务要解除绑定,这个在上面解除绑定的时候分析了该过程,因此这里就不再重复了;第三步,如果服务存在,则停止服务。我们开始分析第三步,第三步这里最终调用ActivityThread的handleStopService方法。
Step13.ActivityThread.handleStopService 1 2 3 4 5 6 private void handleStopService (IBinder token) { Service s = mServices.remove(token); ... s.onDestroy(); ... }
这里如果服务存在则调用服务的onDestroy方法,到这里服务的停止也就结束了。从上面看服务的整个流程相对于Activity简单的多。很容易就看懂了。其实还有一个IntentService,整个服务继承Service,只不过里面多了一个Handler,我们看看这段代码:
1 2 3 4 5 6 7 8 9 10 11 private final class ServiceHandler extends Handler { public ServiceHandler (Looper looper) { super (looper); } @Override public void handleMessage (Message msg) { onHandleIntent((Intent)msg.obj); stopSelf(msg.arg1); } }
如果有Handler就有发送消息的地方,那么发送消息在哪里呢,我们知道当你调用服务的时候会走onStartCommand方法:
1 2 3 4 public int onStartCommand (@Nullable Intent intent, int flags, int startId) { onStart(intent, startId); return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; }
这里会调用onStart方法:
1 2 3 4 5 6 public void onStart (@Nullable Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); }
这里就是发送消息的时候,消息发出后会由上面的ServiceHandler来处理,我们看到构造函数里传入了一个Looper,这个是在onCreate方法中初始化的:
1 2 3 4 5 6 7 8 9 10 11 12 public void onCreate () { super .onCreate(); HandlerThread thread = new HandlerThread ("IntentService[" + mName + "]" ); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler (mServiceLooper); }
这里创建了一个Handler线程,并且获取了它的Looper,用来循环处理消息,因此我们知道同时只能处理一个消息,等前一个消息处理完了才会处理第二个,以此类推,因此需要同时处理的不能用这个Service,另外在ServiceHandler中有个stopSelf用来在消息处理完成后停止自己,因此该服务可以说是用完自动停止,不会一直存在,占用资源。
代码地址: 直接拉取导入开发工具(Intellij idea或者Android studio)
Android_Framework_Source
注 Android开发群:192508518
微信公众账号:Code-MX
注:本文原创,转载请注明出处,多谢。