diff --git a/blogs/Android/Framework/源代码情景分析/Activity 组件的启动过程.md b/blogs/Android/Framework/源代码情景分析/Activity 组件的启动过程.md index 34bbae7..42f2cce 100644 --- a/blogs/Android/Framework/源代码情景分析/Activity 组件的启动过程.md +++ b/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 组件的操作。 +