Android Service 流程分析

启动Service过程


Android Service启动时序图

Android Service启动时序图.png

上图就是Android Service启动时序图,对照图查看代码。

我们在 Activity 中调用 startService() 方法时,直接调用了 调用 ContextWrapperstartService()

1@Override 2public ComponentName startService(Intent service) { 3 return mBase.startService(service); 4}

mBase 就是 ContextImpl,进入 ContextImpl 中查看

1@Override 2public ComponentName startService(Intent service) { 3 warnIfCallingFromSystemProcess(); 4 return startServiceCommon(service, false, mUser); 5} 6 7private ComponentName startServiceCommon(Intent service, boolean requireForeground, 8 UserHandle user) { 9 try { 10 validateServiceIntent(service); 11 service.prepareToLeaveProcess(this); 12 // ActivityManager.getService() 就是获取到的 ActivityManagerService 对象 13 ComponentName cn = ActivityManager.getService().startService( 14 mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded( 15 getContentResolver()), requireForeground, 16 getOpPackageName(), user.getIdentifier()); 17 // ... 省略 对 cn 进行校验 18 return cn; 19 } catch (RemoteException e) { 20 throw e.rethrowFromSystemServer(); 21 } 22}

ActivityManager 中获取 ActivityManagerService 代码如下:

1public static IActivityManager getService() { 2 return IActivityManagerSingleton.get(); 3} 4 5// 通过 Singleton 创建IActivityManager.aidl接口对象,实现类为 `ActivityManagerService` 6private static final Singleton<IActivityManager> IActivityManagerSingleton = 7 new Singleton<IActivityManager>() { 8 @Override 9 protected IActivityManager create() { 10 final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); 11 // 由一下代码可知,IActivityManager 是aidl,也就说明Service的启动过程是一个IPC的过程 12 final IActivityManager am = IActivityManager.Stub.asInterface(b); 13 return am; 14 } 15 };

进入 ActivityManagerService 中查看 startService() 方法

1@Override 2public ComponentName startService(IApplicationThread caller, Intent service, 3 String resolvedType, boolean requireForeground, String callingPackage, int userId) 4 throws TransactionTooLargeException { 5 enforceNotIsolatedCaller("startService"); 6 // ... 省略 Refuse possible leaked file descriptors 对service文件描述和调用包进行判断 7 8 synchronized(this) { 9 final int callingPid = Binder.getCallingPid(); 10 final int callingUid = Binder.getCallingUid(); 11 final long origId = Binder.clearCallingIdentity(); 12 ComponentName res; 13 try { 14 // 调用 ActiveServices 的 startServiceLocked() 方法 15 res = mServices.startServiceLocked(caller, service, 16 resolvedType, callingPid, callingUid, 17 requireForeground, callingPackage, userId); 18 } finally { 19 Binder.restoreCallingIdentity(origId); 20 } 21 return res; 22 } 23}

mServices 是 ActiveServices 类,该类是 AMS(ActivityManagerService) 的辅助类,是对 Service 进行管理的工具类,包含Service的启动、绑定、解绑、销毁等过程。查看 ActiveServicesstartServiceLocked() 方法,一下是ActiveServices中的方法调用过程:

1// ActiveServices#startServiceLocked() 2ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, 3 int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId) 4 throws TransactionTooLargeException { 5 // 调用 startServiceLocked() 6 return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired, 7 callingPackage, userId, false); 8} 9 10// ActiveServices#startServiceLocked() 11ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, 12 int callingPid, int callingUid, boolean fgRequired, String callingPackage, 13 final int userId, boolean allowBackgroundActivityStarts) 14 throws TransactionTooLargeException { 15 16 // ... 省略 17 18 ServiceLookupResult res = 19 retrieveServiceLocked(service, null, resolvedType, callingPackage, 20 callingPid, callingUid, userId, true, callerFg, false, false); 21 22 // 取出 ServiceRecord 对象,后面启动过程中都是使用的它 23 ServiceRecord r = res.record; 24 25 // ... 省略 判断和处理前台服务 26 27 r.lastActivity = SystemClock.uptimeMillis(); 28 r.startRequested = true; // 启动服务标识置为 true 29 r.delayedStop = false; 30 r.fgRequired = fgRequired; 31 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), 32 service, neededGrants, callingUid)); 33 // 调用 startServiceInnerLocked() 方法 34 ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting); 35 return cmp; 36} 37 38// ActiveServices#startServiceInnerLocked() 39ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r, 40 boolean callerFg, boolean addToStarting) throws TransactionTooLargeException { 41 // ... 省略 42 String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false); 43 // ... 省略 44 return r.name; 45} 46 47// ActiveServices#bringUpServiceLocked() 48private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, 49 boolean whileRestarting, boolean permissionsReviewRequired) 50 throws TransactionTooLargeException { 51 // 已经启动,重复启动时,直接发送参数调动 onStartCommand() 方法 52 if (r.app != null && r.app.thread != null) { 53 sendServiceArgsLocked(r, execInFg, false); 54 return null; 55 } 56 57 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0; 58 final String procName = r.processName; 59 HostingRecord hostingRecord = new HostingRecord("service", r.instanceName); 60 ProcessRecord app; 61 62 if (!isolated) { 63 app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false); 64 if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid 65 + " app=" + app); 66 if (app != null && app.thread != null) { 67 try { 68 app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats); 69 // 调用 realStartServiceLocked() 方法 70 realStartServiceLocked(r, app, execInFg); 71 return null; 72 } catch (TransactionTooLargeException e) { 73 throw e; 74 } catch (RemoteException e) { 75 Slog.w(TAG, "Exception when starting service " + r.shortInstanceName, e); 76 } 77 } 78 } else { 79 // ... 省略 80 } 81 // ... 省略 82 return null; 83} 84 85// ActiveServices#realStartServiceLocked() 86private final void realStartServiceLocked(ServiceRecord r, 87 ProcessRecord app, boolean execInFg) throws RemoteException { 88 89 boolean created = false; 90 try { 91 // 调用 ActivityThread 的 scheduleCreateService() 方法 92 app.thread.scheduleCreateService(r, r.serviceInfo, 93 mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo), 94 app.getReportedProcState()); 95 r.postNotification(); 96 created = true; 97 } catch (DeadObjectException e) { 98 throw e; 99 } finally { 100 // ... 省略 101 } 102 // ... 省略 103 104 105 // 如果是启动,并且需要调用 onStartCommand() 方法,给 pendingStarts 集合增加数据, 106 // 因为 onStartCommand() 方法是否会调动是根据 pendingStarts 集合是否有数据来决定是否调用的。 107 // 在后面说参数调用的时候就会知道,如果仅仅是绑定服务,就不会添加,这也就是为什么我们绑定服务时不会回调 onStartCommand() 方法的原因 108 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) { 109 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), 110 null, null, 0)); 111 } 112 // 调用方法,处理参数,从而调用 onStartCommand() 方法 113 sendServiceArgsLocked(r, execInFg, true); 114}

从这里开始分为两步,先通过 ActivityThread 中的方法来启动 Service,然后在通过 ActiveServices 自身的 sendServiceArgsLocked() 方法来处理参数(Intent数据),调用生命周期的 onStartCommand() 方法。注意注释部分,说明了我们仅仅是绑定服务时为什么不会回调 onStartCommand() 方法的原因,后面说绑定Service不会在重复了。

启动过程(attach() 和 onCreate() 方法回调过程)

先看 ActivityThread 中的方法

1// ActivityThread#scheduleCreateService() 2public final void scheduleCreateService(IBinder token, 3 ServiceInfo info, CompatibilityInfo compatInfo, int processState) { 4 updateProcessState(processState, false); 5 CreateServiceData s = new CreateServiceData(); 6 s.token = token; 7 s.info = info; 8 s.compatInfo = compatInfo; 9 // 给 Handler 类 H 发送 CREATE_SERVICE 10 // H 是 ActivityThread 的内部类,继承 Handler 11 sendMessage(H.CREATE_SERVICE, s); 12}

Handler 类 H handleMessage() 方法针对 what 为 CREATE_SERVICE 的处理,调用 handleCreateService() 方法

1case CREATE_SERVICE: 2 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj))); 3 handleCreateService((CreateServiceData)msg.obj); 4 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 5break;

调用 handleCreateService() 方法,内部通过类加载器创建Service东西,然后调用Service的 attach()onCreate() 方法

1// ActivityThread#handleCreateService() 2private void handleCreateService(CreateServiceData data) { 3 4 LoadedApk packageInfo = getPackageInfoNoCheck( 5 data.info.applicationInfo, data.compatInfo); 6 Service service = null; 7 try { 8 // 使用类加载器通过反射的形势创建Service对象 9 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 10 service = packageInfo.getAppFactory() 11 .instantiateService(cl, data.info.name, data.intent); 12 } catch (Exception e) { 13 } 14 15 try { 16 ContextImpl context = ContextImpl.createAppContext(this, packageInfo); 17 context.setOuterContext(service); 18 Application app = packageInfo.makeApplication(false, mInstrumentation); 19 // Serivce 的 attach() 回调,并建立 Service 和 ContextImpl 之间的联系 20 service.attach(context, this, data.info.name, data.token, app, 21 ActivityManager.getService()); 22 service.onCreate(); // Serivce 的 onCreate() 回调 23 // 将Service保存到集合中 final ArrayMap<IBinder, Service> mServices = new ArrayMap<>(); 24 mServices.put(data.token, service); 25 } catch (Exception e) { 26 27 } 28}

通过类加载器创建Service的过程如下:

通过类 LoadedApk#getAppFactory() 方法可以知道获取到的是 AppComponentFactory 对象,

1public AppComponentFactory getAppFactory() { 2 return mAppComponentFactory; 3} 4 5// 给 mAppComponentFactory 赋值 6private AppComponentFactory createAppFactory(ApplicationInfo appInfo, ClassLoader cl) { 7 if (appInfo.appComponentFactory != null && cl != null) { 8 try { 9 return (AppComponentFactory) cl.loadClass(appInfo.appComponentFactory).newInstance(); 10 } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { 11 Slog.e(TAG, "Unable to instantiate appComponentFactory", e); 12 } 13 } 14 return AppComponentFactory.DEFAULT; 15}

然后调用 AppComponentFactory#instantiateService() 方法,创建Service类,方法实现如下:

1public @NonNull Service instantiateService(@NonNull ClassLoader cl, 2 @NonNull String className, @Nullable Intent intent) 3 throws InstantiationException, IllegalAccessException, ClassNotFoundException { 4 // 通过反射创建Service 5 return (Service) cl.loadClass(className).newInstance(); 6}

上面说了,分为两步。先是启动 Service;然后在处理参数。通过以上步骤,我们知道 Service 已经启动了,它的 attach()onCreate() 都已经调用了,下面我们来看看它的生命周期方法
onStartCommand() 在什么时候调用,在上面已经说过是通过 ActiveServices 自身的 sendServiceArgsLocked() 方法来处理的

参数处理(onStartCommand() 方法回调过程)

1// ActiveServices#sendServiceArgsLocked() 方法 2private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg, 3 boolean oomAdjusted) throws TransactionTooLargeException { 4 final int N = r.pendingStarts.size(); 5 // 集合中没有数据,直接返回。 6 // 如果仅仅是绑定服务,大小为0,这也就是为什么我们绑定服务时不会回调 onStartCommand() 方法的原因 7 // 上面 ActiveServices#realStartServiceLocked() 注释 8 if (N == 0) { 9 return; 10 } 11 12 ArrayList<ServiceStartArgs> args = new ArrayList<>(); 13 // ... 省略 r.pendingStarts 参数处理部分 14 ParceledListSlice<ServiceStartArgs> slice = new ParceledListSlice<>(args); 15 slice.setInlineCountLimit(4); 16 Exception caughtException = null; 17 try { 18 // 调用 ActivityThread 的 scheduleServiceArgs() 方法 19 r.app.thread.scheduleServiceArgs(r, slice); 20 } catch (TransactionTooLargeException e) { 21 } 22}

上面当 r.pendingStarts.size() 为0时,不会继续执行,也就是当仅仅是绑定Service时,不会执行后面的步骤了。接着看 ActivityThread 中的 scheduleServiceArgs() 方法

1// ActivityThread#scheduleServiceArgs() 2public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) { 3 List<ServiceStartArgs> list = args.getList(); 4 5 for (int i = 0; i < list.size(); i++) { 6 ServiceStartArgs ssa = list.get(i); 7 ServiceArgsData s = new ServiceArgsData(); 8 s.token = token; 9 s.taskRemoved = ssa.taskRemoved; 10 s.startId = ssa.startId; 11 s.flags = ssa.flags; 12 s.args = ssa.args; 13 // 给 Handler 类 H 发送 SERVICE_ARGS 14 sendMessage(H.SERVICE_ARGS, s); 15 } 16}

Handler 类 H handleMessage() 方法针对 what 为 SERVICE_ARGS 的处理,调用 handleServiceArgs() 方法

1case SERVICE_ARGS: 2 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj))); 3 handleServiceArgs((ServiceArgsData)msg.obj); 4 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 5break;

调用 handleServiceArgs() 方法,在方法内部调用 Serivce 的 onStartCommand() 回调

1// ActivityThread#handleServiceArgs() 2private void handleServiceArgs(ServiceArgsData data) { 3 Service s = mServices.get(data.token); 4 if (s != null) { 5 try { 6 if (data.args != null) { 7 data.args.setExtrasClassLoader(s.getClassLoader()); 8 data.args.prepareToEnterProcess(); 9 } 10 int res; 11 if (!data.taskRemoved) { 12 // Serivce 的 onStartCommand() 回调 13 res = s.onStartCommand(data.args, data.flags, data.startId); 14 } else { 15 s.onTaskRemoved(data.args); 16 res = Service.START_TASK_REMOVED_COMPLETE; 17 } 18 19 QueuedWork.waitToFinish(); 20 21 try { 22 ActivityManager.getService().serviceDoneExecuting( 23 data.token, SERVICE_DONE_EXECUTING_START, data.startId, res); 24 } catch (RemoteException e) { 25 throw e.rethrowFromSystemServer(); 26 } 27 } catch (Exception e) { 28 } 29 } 30}

以上就是Android中的Service启动流程,就是通过AMS(ActivityManagerService)借助 ActiveServices 来完成,由AMS的定义ActivityManagerService extends IActivityManager.Stub 可知这也是一个IPC过程,最后则都是通过 ActivityThread 来内部类H来处理(H是主线程的Handler),主线程的Loop由 ActivityThread 的 main() 方法开启

1// ActivityThread#main() 2public static void main(String[] args) { 3 Looper.prepareMainLooper(); 4 ActivityThread thread = new ActivityThread(); 5 thread.attach(false, startSeq); 6 if (sMainThreadHandler == null) { 7 sMainThreadHandler = thread.getHandler(); 8 } 9 Looper.loop(); 10}

绑定Service过程

Android Service绑定时序图

Android Service绑定时序图.png

上图就是Android Service启动时序图,绑定Service我们也需要启动Service,也就是需要调用Service 的 attach()onCreate() 方法,由图可知,在调用这两个方法的过程中,ActiveServicesActivityThread 中间的过程是一样的。

我们具体的来看一下

我们在 Activity 中调用 bindService() 方法时,直接调用了 调用 ContextWrapperbindService(),接着调用 ContextImplbindService(),查看 ContextImpl 中的代码

1@Override 2public boolean bindService(Intent service, ServiceConnection conn, int flags) { 3 warnIfCallingFromSystemProcess(); 4 return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null, getUser()); 5} 6 7private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, 8 String instanceName, Handler handler, Executor executor, UserHandle user) { 9 IServiceConnection sd; 10 // mPackageInfo 为 LoadedApk 11 if (mPackageInfo != null) { 12 if (executor != null) { 13 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags); 14 } else { 15 // handler不为null,将 ServiceConnection 封装成 IServiceConnection 16 // IServiceConnection 就是 LoadedApk.ServiceDispatcher.InnerConnection 类 17 // 将 conn 保持到InnerConnection中,handler 为主线程Handler,也就是 ActivityThread的内部类 H 对象 18 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags); 19 } 20 } else { 21 throw new RuntimeException("Not supported in system context"); 22 } 23 validateServiceIntent(service); 24 try { 25 IBinder token = getActivityToken(); 26 if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null 27 && mPackageInfo.getApplicationInfo().targetSdkVersion 28 < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 29 flags |= BIND_WAIVE_PRIORITY; 30 } 31 service.prepareToLeaveProcess(this); 32 // 调用 AMS 的 bindIsolatedService() 方法 33 int res = ActivityManager.getService().bindIsolatedService( 34 mMainThread.getApplicationThread(), getActivityToken(), service, 35 service.resolveTypeIfNeeded(getContentResolver()), 36 sd, flags, instanceName, getOpPackageName(), user.getIdentifier()); 37 if (res < 0) { 38 throw new SecurityException( 39 "Not allowed to bind to service " + service); 40 } 41 return res != 0; 42 } catch (RemoteException e) { 43 throw e.rethrowFromSystemServer(); 44 } 45}

**注意:**在这里需要注意以上注释的地方,因为绑定Service最终客户端要回调 ServiceConnection 对象的 onServiceConnected() 方法,mPackageInfo.getServiceDispatcher() 就是将我们调用 bindService() 方法传递的 ServiceConnection 对象 封装成 IServiceConnection(实现为 LoadedApk#ServiceDispatcher#InnerConnection 类,定义为 InnerConnection extends IServiceConnection.Stub )这是一个aidl接口,这是因为Service启动和绑定时跨进程的,普通的 ServiceConnection 是不能款进程传输的,所以需要进行封装与转换成aidl类型。

先看绑定Service的启动过程

调用 AMS 的 bindIsolatedService() 方法

1// ActivityManagerService#bindIsolatedService() 2public int bindIsolatedService(IApplicationThread caller, IBinder token, Intent service, 3 String resolvedType, IServiceConnection connection, int flags, String instanceName, 4 String callingPackage, int userId) throws TransactionTooLargeException { 5 6 synchronized(this) { 7 // 调用 ActiveServices 的 bindServiceLocked() 方法 8 return mServices.bindServiceLocked(caller, token, service, 9 resolvedType, connection, flags, instanceName, callingPackage, userId); 10 } 11}

由AMS调用 ActiveServices 中的 bindServiceLocked() 方法

1// ActiveServices#bindServiceLocked() 2int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service, 3 String resolvedType, final IServiceConnection connection, int flags, 4 String instanceName, String callingPackage, final int userId) 5 throws TransactionTooLargeException { 6 // ... 省略 7 8 // 绑定服务时,调用 ServiceRecord 的 retrieveAppBindingLocked() 方法, 9 // 在该方法中给 ServiceRecord的bindings 添加绑定记录 10 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); 11 ConnectionRecord c = new ConnectionRecord(b, activity, 12 connection, flags, clientLabel, clientIntent, 13 callerApp.uid, callerApp.processName, callingPackage); 14 IBinder binder = connection.asBinder(); 15 // 保存到 ServiceRecord 的 connections 集合中 16 s.addConnection(binder, c); 17 b.connections.add(c); 18 19 // ... 省略 20 if ((flags&Context.BIND_AUTO_CREATE) != 0) { 21 s.lastActivity = SystemClock.uptimeMillis(); 22 // 调用 bringUpServiceLocked() 方法,后面的启动过程和启动Service一样 23 if (bringUpServiceLocked(s, service.getFlags(), callerFg, false, 24 permissionsReviewRequired) != null) { 25 return 0; 26 } 27 } 28 29 // ... 省略 30 return 1; 31}

注意,上面注释部分,绑定服务时,我们将连接对象保存到了 ServiceRecord 中。

绑定服务到这里,后面调用 attach() 和 onCreate() 方法就和启动服务时一样的了,在 bringUpServiceLocked() 中 调用
realStartServiceLocked() 方法,接着继续往下调用。

和启动Service不一样的是,在 realStartServiceLocked() 方法中会调用 requestServiceBindingsLocked() 方法,处理绑定服务的过程

绑定过程(onBind() 或者 onRebind() 方法回调过程)

ActiveServices 中的requestServiceBindingsLocked() 方法

1// ActiveServices#requestServiceBindingsLocked() 2private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg) 3 throws TransactionTooLargeException { 4 // 根据 ServiceRecord的bindings 是否有数据调用 requestServiceBindingLocked() 方法,在上一步给它添加了数据 5 for (int i=r.bindings.size()-1; i>=0; i--) { 6 IntentBindRecord ibr = r.bindings.valueAt(i); 7 if (!requestServiceBindingLocked(r, ibr, execInFg, false)) { 8 break; 9 } 10 } 11}

根据是否有连接对象判断是否需要调用 ActiveServices 中的requestServiceBindingLocked() 方法,绑定Service在 ActiveServices 中的 bindServiceLocked() 方法中添加了,所以集合肯定不会为空

1// ActiveServices#requestServiceBindingLocked() 2private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i, 3 boolean execInFg, boolean rebind) throws TransactionTooLargeException { 4 5 if ((!i.requested || rebind) && i.apps.size() > 0) { 6 try { 7 bumpServiceExecutingLocked(r, execInFg, "bind"); 8 r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE); 9 // 调用 ActivityThread 的 scheduleBindService() 方法 10 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind, 11 r.app.getReportedProcState()); 12 if (!rebind) { 13 i.requested = true; 14 } 15 i.hasBound = true; 16 i.doRebind = false; 17 } catch (TransactionTooLargeException e) { 18 return false; 19 } 20 } 21 return true; 22}

继续进入 ActivityThread 中调用 scheduleBindService() 方法

1// ActivityThread#scheduleBindService 2public final void scheduleBindService(IBinder token, Intent intent, 3 boolean rebind, int processState) { 4 updateProcessState(processState, false); 5 BindServiceData s = new BindServiceData(); 6 s.token = token; 7 s.intent = intent; 8 s.rebind = rebind; 9 10 // 给 Handler 类 H 发送 BIND_SERVICE 11 sendMessage(H.BIND_SERVICE, s); 12}

Handler 类 H handleMessage() 方法针对 what 为 BIND_SERVICE 的处理,调用 handleBindService() 方法

1case BIND_SERVICE: 2 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind"); 3 handleBindService((BindServiceData)msg.obj); 4 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 5break;

ActivityThread 中调用 handleBindService() 方法

1// ActivityThread#handleBindService 2private void handleBindService(BindServiceData data) { 3 Service s = mServices.get(data.token); 4 if (s != null) { 5 try { 6 data.intent.setExtrasClassLoader(s.getClassLoader()); 7 data.intent.prepareToEnterProcess(); 8 try { 9 if (!data.rebind) { 10 // 调用 Service 的 onBind() 方法 11 IBinder binder = s.onBind(data.intent); 12 // 这里调用 ActivityManagerService 的 publishService() 方法, 13 ActivityManager.getService().publishService( 14 data.token, data.intent, binder); 15 } else { 16 // 如果是重新绑定,就调用 Service 的 onRebind() 方法 17 s.onRebind(data.intent); 18 ActivityManager.getService().serviceDoneExecuting( 19 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); 20 } 21 } catch (RemoteException ex) { 22 throw ex.rethrowFromSystemServer(); 23 } 24 } catch (Exception e) { 25 if (!mInstrumentation.onException(s, e)) { 26 throw new RuntimeException( 27 "Unable to bind to service " + s 28 + " with " + data.intent + ": " + e.toString(), e); 29 } 30 } 31 } 32}

在上面的方法中我们已经看到了 Service 的 onBind() 或者 onRebind() 方法已经被调用了,那么对于Service类来说已经执行完成了。但是我们绑定Service,客户端需要拿到IBinder对象,这个对象是在 ServiceConnection 对象的回调 onServiceConnected() 方法取到的,所以我们继续看看这个过程是怎样的。

调用 ServiceConnection 对象的回调 onServiceConnected() 方法过程

1// 这里调用 ActivityManagerService 的 publishService() 方法, 2ActivityManager.getService().publishService(data.token, data.intent, binder);

查看以上这句代码,调用 ActivityManagerServicepublishService()方法

1// ActivityManagerService#publishService() 2public void publishService(IBinder token, Intent intent, IBinder service) { 3 synchronized(this) { 4 if (!(token instanceof ServiceRecord)) { 5 throw new IllegalArgumentException("Invalid service token"); 6 } 7 // 调用 ActiveServices 的 publishServiceLocked() 方法 8 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 9 } 10}

然后调用 ActiveServicespublishServiceLocked() 方法

1// ActiveServices#publishServiceLocked() 2void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) { 3 // 从 ServiceRecord 的 connections 集合中取出数据 4 ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections(); 5 for (int conni = connections.size() - 1; conni >= 0; conni--) { 6 ArrayList<ConnectionRecord> clist = connections.valueAt(conni); 7 for (int i=0; i<clist.size(); i++) { 8 ConnectionRecord c = clist.get(i); 9 try { 10 // c.conn 为 IServiceConnection 对象 11 // 实际就是 LoadedApk.ServiceDispatcher.InnerConnection 类 12 c.conn.connected(r.name, service, false); 13 } catch (Exception e) { 14 15 } 16 } 17 } 18}

这个地方我们先从 ServiceRecord 取出数据,取出来的数据就是包含了客户端 ServiceConnection 对象的aidl接口对象 IServiceConnection (实现类为 LoadedApk#ServiceDispatcher#InnerConnection),所以调用的就是 LoadedApk#ServiceDispatcher#InnerConnection 的 connected() 方法

1// LoadedApk 内部类 InnerConnection 的 connected() 方法,也就是上面的 c.conn.connected() 方法 2private static class InnerConnection extends IServiceConnection.Stub { 3 @UnsupportedAppUsage 4 final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher; 5 6 InnerConnection(LoadedApk.ServiceDispatcher sd) { 7 mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd); 8 } 9 10 public void connected(ComponentName name, IBinder service, boolean dead) 11 throws RemoteException { 12 LoadedApk.ServiceDispatcher sd = mDispatcher.get(); 13 if (sd != null) { 14 // 调用 LoadedApk.ServiceDispatcher 的 connected() 方法 15 sd.connected(name, service, dead); 16 } 17 } 18}

调用 LoadedApk#ServiceDispatcher 的 connected() 方法

1// LoadedApk.ServiceDispatcher#connected() 2public void connected(ComponentName name, IBinder service, boolean dead) { 3 if (mActivityExecutor != null) { 4 mActivityExecutor.execute(new RunConnection(name, service, 0, dead)); 5 } else if (mActivityThread != null) { 6 // 由 ContextImpl#bindServiceCommon() 方法中可知,mActivityThread 就是 ActivityThread 的 H对象(主线程的Handler),不为null 7 // RunConnection 的 run方法中调用 doConnected() 方法 8 // 因为是通过主线程的Handler调用的方法,所以客户端的ServiceConnection#onServiceConnected()运行在主线程 9 mActivityThread.post(new RunConnection(name, service, 0, dead)); 10 } else { 11 doConnected(name, service, dead); 12 } 13}

由前面的代码可知,这里的 mActivityThread 不会为 null ,而且就是就是 ActivityThread 的 H对象(主线程的Handler),会调用mActivityThread.post运行任务。RunConnection 代码如下:

1// RunConnection 类代码 2private final class RunConnection implements Runnable { 3 public void run() { 4 if (mCommand == 0) { 5 // 调用 doConnected() 方法 6 doConnected(mName, mService, mDead); 7 } else if (mCommand == 1) { 8 doDeath(mName, mService); 9 } 10 } 11}

在 RunConnection 中调用 LoadedApk 类的 doConnected() 方法

1// LoadedApk#doConnected() 2public void doConnected(ComponentName name, IBinder service, boolean dead) { 3 // ... 省略 4 5 // 由 ContextImpl#bindServiceCommon() 方法中可知,mConnection 就是客户端的 ServiceConnection 对象,回调它的 onServiceConnected() 方法,完成绑定过程 6 if (service != null) { 7 mConnection.onServiceConnected(name, service); 8 } else { 9 // The binding machinery worked, but the remote returned null from onBind(). 10 mConnection.onNullBinding(name); 11 } 12}

service不为null时,调用 mconnection 的 onServiceConnected() 方法,mconnection 就是客户端的 ServiceConnection 对象,在前面 ContextImplbindServiceCommon() 方法说明时有注释进行说明了。

以上就是绑定Service以及回调给客户端IBinder东西的完整过程,也就是我们在使用绑定Service时系统的调用过程。对于解绑和停止Service相关类也就是这些,这里就一一贴出代码了,一下提供解绑Service和停止Service的时序图。

解绑Service过程

Android Service解绑时序图.png

停止Service过程

Android Service停止时序图.png

本文转自 https://www.jianshu.com/p/752d51d487de,如有侵权,请联系删除。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )