Update Activity 组件的启动过程.md

master
Omooo 5 years ago
parent 2da5b3e705
commit c5012afd7b
  1. 97
      blogs/Android/Framework/源代码情景分析/Activity 组件的启动过程.md

@ -60,6 +60,103 @@ public class Instrumentation {
ActivityMAnagerNative#getDefault 实现如下:
```java
public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
static public IActivityManager asInterface(IBinder obj)
{
IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ActivityManagerProxy(obj);
}
static public IActivityManager getDefault()
{
if (gDefault != null) {
return gDefault;
}
IBinder b = ServiceManager.getService("activity");
gDefault = asInterface(b);
return gDefault;
}
private static IActivityManager gDefault;
}
```
第一次调用 ActivityManagerNative 类的静态成员函数 getDefault 时,它便会通过 ServiceManager 来获得一个名称为 "activity" 的 Java 服务代理对象,即获得一个引用了 ActivityManagerService 的代理对象。然后调用静态函数 asInterface 将这个代理对象封装成一个类型为 ActivityManagerProxy 的代理对象,最后将它保存在静态成员变量 gDefault 中。这样,以后再调用 ActivityManagerNative 类的静态成员函数 getDefault 时,就可以直接获得 ActivityManagerService 的一个代理对象了。
回到 Instrumentation 类的成员函数 execStartActivity 中,接下来就调用 ActivityManagerProxy 类的成员函数 startActivity 通知 AMS 启动一个 Activity 组件。
```java
class ActivityManagerProxy implements IActivityManager
{
public int startActivity(IApplicationThread caller, Intent intent, IBinder resultTo, ...) {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
intent.writeToParcel(data, 0);
//...
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
return result;
}
}
```
首先将前面传进来的参数写入到 Parcel 对象 data 中,接着再通过 ActivityManagerProxy 类内部的一个 Binder 代理对象 mRemote 向 AMS 发送一个类型为 START_ACTIVITY_TRANSACTION 的进程间通信请求。
传递给 AMS 的参数比较多,不过我们需要重点关注的参数有三个,它们分别是 caller、intent 和 resultTo。其中,参数 caller 指向 Launcher 组件所运行在的应用程序进程的 ApplicationThread 对象;参数 intent 包含了即将要启动的 MainActivity 组件的信息;参数 resultTo 指向 ActivityManagerService 内部的一个 ActivityRecord 对象,它里面保存了 Launcher 组件的详细信息。
以上都是在应用程序 Launcher 中执行的,接下来就是在 AMS 中去处理 Launcher 组件发出的类型为 START_ACTIVITY_TRANSACTION 的进程间通信请求。
```java
public final class ActivityManagerService extends ActivityManagerNative
{
public final int startActivity(IApplicationThread caller, Intent intent, IBinder resultTo, ...){
return mMainStack.startActivity(...);
}
}
```
AMS 类的成员函数 startActivity 用来处理类型为 START_ACTIVITY_TRANSACTION 的进程间通信请求。
AMS 类有一个类型为 ActivityStack 的成员变量 mMainStack,用来描述一个 Activity 组件堆栈,然后调用它的 startActivityMayWait 来进一步处理。
```java
public class ActivityStack {
final int startActivityMayWait(IApplicationThread caller, Intent intent, IBinder resultTo, ...) {
ActivityInfo aInfo;
ResolveInfo rInfo = AppGlobals.getPackageManager().resolveIntent(intent, ...);
aInfo = rInfo != null ? rInfo.activityInfo : null;
int res = startActivityLocked(caller, intent, aInfo, ...);
return res;
}
}
```
首先会到 PKMS 中去解析参数 intent 的内容,以便可以获得即将启动的 Activity 组件的更多信息;接着调用 startActivityLocked 来继续执行启动 Activity 组件的工作。
```java
public class ActivityStack {
final int startActivityLocked(IApplicationThread caller, Intent intent, ...) {
ProcessRecord callerApp = null;
if (caller != null) {
callerApp = mService.getRecordForAppLocked(caller);
if (callerApp != null) {
callingPid = callerApp.pid;
callingUid = callerApp.info.uid;
}
}
ActivityRecord r = new ActivityRecord(mService, ...);
return startActivityUncheckedLocked(r, ...);
}
}
```
在 AMS 中,每一个应用程序进程都使用一个 ProcessRecord 对象来描述,并且保存在 AMS 内部。ActivityStack 类的成员变量 mService 指向了 ASM,通过调用它的成员函数 getRecordForAppLocked 来获得与参数 caller 对应的一个 ProcessRecord 对象 callerApp。前面提到,参数 caller 指向的是 Launcher 组件所运行在的应用程序进程的一个 ApplicationThread 对象,因此,得到的 ProcessRecord 对象 callerApp 实际上就指向了 Launcher 组件所运行在的应用程序进程。
ActivityStack 类的成员变量 mHistory 用来描述系统的 Activity 组件堆栈。在这个堆栈中,每一个已经启动的 Activity 组件都使用一个 ActivityRecord 对象来描述。然后创建一个 ActivityRecord 对象 r 来描述即将启动的 Activity 组件,即 MainActivity 组件。
现在,ActivityStack 类就得到了请求 AMS 执行启动 Activity 组件操作的源 Activity 组件,以及要启动的目标 Activity 组件的信息了,它们分别保存在 ActivityRecord 对象 sourceRecord 和 r 中。最后调用 startActivityUncheckedLocked 进一步执行启动目标 Activity 组件的操作。

Loading…
Cancel
Save