API 28

一、bindService() 调用流程时序图

bindService() 调用流程

二、bindService() 调用流程文字描述

bindService() ->
	ContextImpl#bindService() ->
		ContextImpl#bindServiceCommon() ->
			// mPackageInfo 类型为 LoadedApk
			// getServiceDispatcher() 方法调用了 LoadedApk#ServiceDispatcher#getServiceDispatcher(),最终返回 LoadedApk#ServiceDispatcher#InnerConnection
			IServiceConnection sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
			AMS#bindService() ->
				ActiveServices#bindServiceLocked() ->
					retrieveServiceLocked() ->
						// 有个 ServiceMap 内部类,用于绑定用户和其对应的 Service
						ServiceMap smap = getServiceMapLocked(userId);
						// comp 默认不为空
						final ComponentName comp = service.getComponent();
						从 smap 中获取 ServiceRecord 对象:
							a 若存在,则取出
							b 若不存在,则创建 ServiceRecord 对象
						作为参数构造 ServiceLookupResult 对象实例后返回
					bringUpServiceLocked() ->
						若 Service 已经启动
							if (r.app != null && r.app.thread != null) {
								sendServiceArgsLocked(r, execInFg, false);
								return null;
							}
						若 Service 没有启动
							获取 Service 所在进程是否存在
								存在:realStartServiceLocked()
									ActivityThread#ApplicationThread#scheduleCreateService()
										// 从 AMS 所在进程转到客户端进程
										ActivityThread#handleCreateService()
											// 获取 LoadedApk 实例
											LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);
											// instantiateService() 方法反射创建 Service 实例
											service = packageInfo.getAppFactory().instantiateService(cl, data.info.name, data.intent);
											// 创建 ContextImpl 实例
											ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
											// 将创建的 Service 设置为 ContextImpl 的 mOuterContext
											context.setOuterContext(service);
											// 创建 Application(有就不创建,没有就创建)
											packageInfo.makeApplication(false, mInstrumentation);
											// 调用 Service#onCreate(),CREATE_SERVICE 消息处理完毕
											service.onCreate();
									// 这里是 AMS 所在进程
									requestServiceBindingsLocked()
										requestServiceBindingLocked()
											ActivityThread#ApplicationThread#scheduleBindService()
												// 从 AMS 所在进程转到客户端进程
												ActivityThread#handleBindService()
													// 调用 Service#onBind()
													s.onBind(data.intent);
													ActivityManager.getService().publishService()
														ActivityManagerService#publishService()
															ActiveServices#publishServiceLocked()
																IntentBindRecord b = r.bindings.get(filter);
																b.binder = service;
																b.requested = true;
																b.received = true;
																// conn:ConnectionRecord 类的成员变量 IServiceConnection
																// ConnectionRecord 在 ActiveServices#bindServiceLocked() 中创建,其第三个参数即 conn
																// 一直往上找,该参数是在一开始的 ContextImpl#bindServiceCommon() 中被赋值,实际类型为 LoadedApk#ServiceDispatcher#InnerConnection
																// IServiceConnection,实现了 Binder 机制?
																// 		在 LoaeddApk 中发现 static class InnerConnection extends IServiceConnection.Stub,证明 IServiceConnection 确实实现了 Binder 机制
																// 因为 conn 实际类型为 LoadedApk#ServiceDispatcher#InnerConnection
																// 所以 conn.connected 对应 LoadedApk#ServiceDispatcher#InnerConnection#connected()
																c.conn.connected(r.name, service, false);
																	LoadedApk.ServiceDispatcher sd = mDispatcher.get();
																	sd.connected(name, service, dead);
																		// mActivityThread 是在 ContextImpl#bindService() 中被赋值,类型为 Handler,不为空
																		if (mActivityThread != null) {
																			// RunConnection implements Runnable,查看其 run() 方法
																			mActivityThread.post(new RunConnection(name, service, 0, dead));
																				RunConnection#run()doConnected(mName, mService, mDead);
																						// 这里的 service 是从 ActivityThread#handleBindService() 方法中传下来的
																						//	IBinder binder = s.onBind(data.intent);
																						//	ActivityManager.getService().publishService(data.token, data.intent, binder);
																						// publishService() 方法的第三个参数 binder 是 onServiceConnected() 方法的第二个参数 service
																						// 而 binder 是 Service#onBind() 的返回值,这也是我们平时在写 Service#onBind() 方法时,方法要返回一个远程 Binder 接口的实现类
																						// 且 mConnection 是我们在代码中创建的 ServiceConnection 实例,通过 ContextImpl#bindService() 传下来
																						// 因此我们在 Connection#onServiceConnected() 方法中就能获取到远程 Binder 本地代理的原因
																						mConnection.onServiceConnected(name, service);
																		} else {
																			doConnected(name, service, dead);
																		}
																
									return null;
								不存在:略(下次说)
					// s.app:Service 对应的 ProcessRecord 不为空
					// b.intent.received:在 bindService 过程中调用 publishService() 时,当前值被置为 true
					if (s.app != null && b.intent.received)
						// Service 已经启动,现在开始连接
						c.conn.connected(s.name, b.intent.binder, false);
					// b.intent.requested:在 bindService 过程中调用 publishService() 时,当前值被置为 true
					else if (!b.intent.requested) // if 判断为 false
						requestServiceBindingLocked() // 不执行

相关文章:

猜你喜欢
相关资源
相似解决方案