前言
要想启动一个应用程序,首先要保证这个应用程所需要的应用程序进程已经创建启动。AMS在启动应用程序时,会检查这个应用程序需要的应用程序进程是否存在,不存在就会请求Zygote孵化器进程来启动需要的应用程序进程。因此应用程序进程启动过程可以概括为两个部分:
- AMS发送启动应用程序进程请求
- Zygote接收请求并创建应用程序进程
关于这部分的具体流程分析可参考《Android进阶解密》第二章内容。本文重点分析Zygote创建应用程序进程走到ActivityThread的main方法后,创建Application的流程。
进入ActivityThread的main方法,需要关注的核心代码如下:
frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
...
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
// 需要关注的代码
thread.attach(false);
...
Looper.loop();
...
}
接下来进入attach方法,代码很多,但是需要重点关注的就这几行:
private void attach(boolean system) {
...
// 注释1
final IActivityManager mgr = ActivityManager.getService();
try {
// 注释2
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
}
如果对Binder机制稍有了解,你就会知道,注释1处调用ActivityManager的getService方法来获取AMS的代理对象,接着调用AMS的attachApplication方法。这里与Android8.0之前的代码逻辑有些不同,Android8.0之前是通过ActivityManagerNative的getDefault来获取AMS的代理对象的,现在这个逻辑封装到了ActivityManager中而不是ActivityManagerNative中。这里先查看ActivityManager的getService方法:
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
// 注释1
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
// 注释2
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
在注释1处获取IBinder类型的AMS引用(binder对象),接着在注释2处将它转换成IActivityManager类型的对象(也就是AMS的代理对象),这段代码采用的AIDL,IActivityManager.java文件是由AIDL工具在编译时自动生成的,IActivityManager.aidl的文件路径为frameworks/base/core/java\android/app/IActivityMananger.aidl。要实现跨进程通信,服务端也就是AMS只需要继承IActivityManager.Stub类并实现相应的方法就可以了。Android8.0之前并没有采用AIDL,用AMS的代理对象ActivityManagerProxy来与AMS进行通信,Android8.0去除了ActivityManagerNative的内部类ActivityManagerProxy,代替它的是IActivityManager,它是AMS在本地的代理。言归正传,回到attach方法,接下来进入AMS的attachApplication方法(跨进程通信,AMS在SystemServer进程)
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId