From 02385af2741682e254bca3eee2d72a850395e5f0 Mon Sep 17 00:00:00 2001 From: Omooo <869759698@qq.com> Date: Wed, 20 May 2020 17:57:29 +0800 Subject: [PATCH] =?UTF-8?q?Create=20Service=20=E7=BB=84=E4=BB=B6=E7=9A=84?= =?UTF-8?q?=E5=90=AF=E5=8A=A8=E8=BF=87=E7=A8=8B.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service 组件的启动过程.md | 152 ++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 blogs/Android/Framework/源代码情景分析/四大组件的启动过程/Service 组件的启动过程.md diff --git a/blogs/Android/Framework/源代码情景分析/四大组件的启动过程/Service 组件的启动过程.md b/blogs/Android/Framework/源代码情景分析/四大组件的启动过程/Service 组件的启动过程.md new file mode 100644 index 0000000..b5d1830 --- /dev/null +++ b/blogs/Android/Framework/源代码情景分析/四大组件的启动过程/Service 组件的启动过程.md @@ -0,0 +1,152 @@ +--- +Service 组件的启动过程 +--- + +#### Service 组件在新进程中的启动过程 + +在我们调用 Context 的 startService 时,其实是调用到 ContextImpl 的 startService: + +```java +class ContextImpl extends Context { + + @Override + public ComponentName startService(Intent service) { + ComponentName cn = ActivityManagerNative.getDefault().startService( + mMainThread.getApplicationThread(), service, + service.resolveTypeIfNeeded(getContextResolver())); + return cn; + } +} +``` + +获取 AMS 的代理对象去处理 startService 的请求: + +```java +// ActivityManagerProxy +public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType) { + Parcel data = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeStrongBinder(caller); + mRemote.transact(START_SERVICE_TRANSACTION, data, ...); +} +``` + +接着再通过 ActivityManagerProxy 类内部的一个 Binder 代理对象 mRemote 向 AMS 发送一个类型为 START_SERVICE_TRANSACTION 的进程间通信请求。 + +接下来就是在 AMS 中去处理 Client 组件发送来的类型为 START_SERVICE_TRANSACTION 的进程间通信请求。 + +```java +// AMS +public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType) { + ComponentName res = startServiceLocked(caller, service, ...); + return res; +} + +ComponentName startServiceLocked(IApplicationThread caller, Intent service, ...) { + ServiceLookupResult res = retrieveServiceLocked(service, ...); + ServiceRecord r = res.record; + bringUpServiceLocked(r, service.getFlags()); + return r.name; +} +``` + +在 AMS 中,每一个 Service 组件都使用一个 ServiceRecord 对象来描述,就像每一个 Activity 组件都使用一个 ActivityRecord 对象来描述一样。 + +首先调用 retrieveServiceLocked 在 AMS 中查找是否存在与参数 service 对应的一个 ServiceRecord 对象。如果不存在,AMS 就会到 PKMS 中去获取与参数 service 对应的一个 Service 组件的信息,然后再将这些信息封装成一个 ServiceRecord 对象,最后调用 bringUpServiceLocked 来启东 ServiceRecord 对象 r 所描述的一个 Service 组件。 + +```java +// AMS +private final boolean bringUpServiceLocked(ServiceRecord r, ...) { + final String appName = r.processName; + ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid); + if (app != null && app.thread != null) { + realStartServiceLocked(r, app); + return true; + } + if (startProcessLocked(appName, r.appInfom, "service", ...)) { + return false; + } + if (!mPendingServices.contains(r)) { + mPendingServices.add(r); + } + return true; +} +``` + +首先判断该 Service 组件所在的进程是否已经创建了,如果没有创建,就会去执行 startProcessLocked 去创建一个应用程序进程,并且把该 Service 添加到 mPendingService 列表中。 + +startProcessLocked 就是调用 Process 类的 start 来创建一个新的应用程序进程,创建完成之后,新的应用程序进程会把 ApplicationThread 传递给 AMS,以便 AMS 可以和这个新创建的应用程序进程通信。新创建的应用程序进程会向 AMS 发送一个 ATTACH_APPLICATION_TRANSACTION 的进程间通信请求。 + +```java +// AMS +private final boolean attachApplicationLocked(IApplicationThread thread, int pid) { + ProcessRecord app = mPidsSlefLocked.get(pid); + app.thread = thread; + if (mPendingServices.size() > 0) { + ServiceRecord sr = null; + for (int i=0;i