Update Service 组件的启动过程.md

master
Omooo 4 years ago
parent 6703bd2146
commit b8a3b2b5a9
  1. 86
      blogs/Android/Framework/源代码情景分析/四大组件的启动过程/Service 组件的启动过程.md

@ -326,3 +326,89 @@ class ServiceRecord extends Binder {
当一个应用程序进程绑定了一个 Service 组件之后,用来描述这个应用程序进程的一个 ProcessRecord 对象就会被保存在用来描述这个被绑定的 Service 组件的一个 ServiceRecord 对象的成员变量 bingdigs 中。由于一个 Service 组件可能会被多个应用程序进程绑定,因此,用来描述这个 Service 组件的一个 ServiceRecord 对象就会使用一个 IntentBindRecord 对象来描述这些应用程序进程,并且以一个 FilterComparison 对象为关键字保存在该 ServiceRecord 对象的成员变量 bingdings 中。
```java
// AMS
private final boolean bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean whileRestarting) {
final String appName = r.processName;
ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
if (app != null && pp.thread != null) {
realStartServiceLocked(r, app);
return true;
}
}
```
首先也是会先判断该 Service 对应的应用程序进程是否已经存在,如果存在,就调用 realStartServiceLocked 来启动 Service。
```java
// AMS
private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app) {
r.app = app;
app.services.add(r);
app.thread.scheduleCreateService(r, r.serviceInfo);
requestServiceBindingsLocked(r);
}
```
其实也是通过类型为 ApplicationThreadProxy 的 Binder 代理对象,它指向了 ProcessRecord 对象 app 所描述的应用程序进程中的一个 ApplicationThread 对象。让它来代理启动该 Service 组件。和之前一样,就是发了一个 SCHEDULE_CREATE_SERVICE_TRANSACTION 的进程间通信请求。
ServiceRecord 对象 r 所描述的 Service 组件启动完成之后,AMS 就需要将它连接到请求绑定它的一个 Activity 组件中,这是通过 AMS 的 requestServiceBindingsLocked 来实现的。
```java
// AMS
private final void requestServiceBindingsLocked(ServiceRecord r) {
Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
while (bindings.hasNext()) {
IntentBindRecord i = bindings.next();
if (!requestServiceBindingLocked(r, i, false)) {
break;
}
}
}
```
在 ServiceRecord 对象 r 的成员变量 bindings 中,保存了一系列 IntentBindRecord 对象,每一个 IntentBindRecord 对象都用来描述若干个需要将 ServiceRecord 对象 r 所描述的 Service 组件绑定到它们里面去的应用程序进程。
```java
// AMS
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i, boolean rebind) {
if ((!i.requested || rebind) && i.apps.size() > 0) {
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
if (!rebind) {
i.requested = true;
}
return true;
}
}
```
参数 rebind 用来描述是否要将 ServiceRecord 对象 r 所描述的 Service 组件重新绑定到 IntentBindRecord 对象 i 所描述的应用程序进程中。从前面的调用过程可以知道,参数 rebind 的值为 false,这意味着 IntentBindRecord 对象 i 所描述的应用程序进程是第一次请求绑定 ServiceRecord 对象 r 所描述的 Service 组件的。
接下来就是 AMS 会请求应用程序 Activity 组件返回 Service 组件内部的一个 Binder 本地对象。
```java
// ApplicationThreadProxy
public final void scheduleBindService(IBinder token, Intent intent, boolean rebind) {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
intent.writeToParcel(data, 0);
mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
data.recycle();
}
```
通过 ApplicationThreadProxy 类内部的一个 Binder 代理对象 mRemote 向应用程序发送一个类型为 SCHEDULE_BIND_SERVICE_TRANSACION 的进程间通信请求。
接下来就会在应用程序进程处理一个 H.BIND_SERVICE 的消息:
```java
// ActivityThread
private final void handleBindService(BindServiceData data) {
Service s = mService.get(data.token);
IBinder binder = s.onBind(data.intent);
ActivityManagerNative.getDefault().publishService(data.token, data.intent, binder);
}
```
BindServiceData 对象 data 的成员变量 token 指向了一个 Binder 代理对象,它引用了 AMS 中的一个 ServiceRecord 对象,而这个 ServiceRecord 对象是用来描述应用程序的 Service 组件的。
Loading…
Cancel
Save