Zygote进程
Android系统中DVM(Dalvik虚拟机)和ART、应用程序进程以及系统关键服务的SystemServer进程都是由Zygote创建的。
Zygote(孵化器)是通过fork(复制)进程的形式来创建应用程序进程以及SystemServer,同时Zygote进程在启动的时候会fork Dalvik/ART
所以由Zygote创建的进程都拥有一个独立的DVM/ART虚拟机的实例副本。这也是为什么Android中应用程序是独立、安全、稳定的,不会因为一个进程出现错误导致所有进程被Kill。
Zygote进程启动
时序图:
SystemServer进程
SystemServer进程主要用于创建系统服务,例如AMS、WMS、和PMS都是由它来创建的。
Service进程启动
时序图
Launcher
当系统启动到最后一步时,会启动一个应用程序,也就是我们通常看到的应用桌面,它被称作Launcher,在Launcher程序启动的时候会请求PackageManagerService来获取当前系统已安装的应用程序,并将其应用信息封装成快捷方式展现在我们的屏幕桌面上,这样用户通过点击应用图标就可以启动应用程序了。
所以Launcher由两个特点:
时序图
图示:
如果启动一个应用程序,AMS会检测该应用程序进程是否存在,如果不存在则向Zygote进行请求创建。
我们知道Zygote的Java框架层中创建了一个服务端的Socekt,用于等待AMS创建新的应用进程请求。AMS发起请求后,Zygote会fock自身进程来创建应用程序,这样应用程序进程在启动时就拥有了虚拟机实例,同时也创建了Binder线程池和消息循环,这样运行在应用程序进程中的应用程序就可以进行进程间通信以及消息处理了。
我们看到该时序图和上文提到的SystemServer启动过程时序图有相似之处。共同点都是从ZygoteInit调用RuntimeInit的applicationInit开始,后续执行流程一样。
*** 注:为什么Android会选择抛出MethodArgsCall异常的方式来调用方法而不是直接调用SystemService的main方法或ActivityThread的main方法?**
**是因为抛出异常的处理会清除所有的设置过程需要的堆栈帧(内存优化) **
ActivityThread是用于管理当前应用程序进程的主线程。其部分关键源码如下:
public static void main(String[] args){
...
// 创建主线程Looper
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if(sMainThreadHandler == null){
// 创建主线程H类
sMainThreadHandler = thread.getHandler();
}
if(false){
Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// Looper开始工作
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
Activity启动分为:根Activity启动和普通Activity启动。而普通Activity与根Activity启动方式类似,根Activity启动更具有代表性。
根Activity启动过程比较复杂,大致分为3个部分:Launcher请求AMS过程、AMS到ApplicationThread调用过程、ActivityThread启动Activity。
*** 注:IActivityManager为AMS的代理对象,它是在Instrumentation中通过ActivityManager.getService()方法获取的。见下文ActivityManager源码: **
public static IActivityManager getService(){
return IActivityManagerSingleton.get();
}
private static final Singleton IActivityManagerSingleton = new Singleton(){
@Override
protected IActivityManager create(){
// Binder类型的AMS引用
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
// 所以此处的IActivityManager实则是AMS的代理对象
final IActivityManager am = IActivityManager.Stub.asInteface(b);
return am;
}
}
// Android8.0使用的AIDL的形式来与AMS进程间通信的,Android7.0则是使用类似于AIDL的ActivityManagerProxy代理对象来实现的。
*** 注:ApplicationThread是ActivityThread的内部类,它继承自IApplicationThread.Stub。它用于和AMS进行进程间通信**
AMS与应用程序进程通信图示:
*** 注:H类为ActivityThread的内部类,它继承Handler。由于ApplicationThread的代码是运行在Binder线程池中的,所以通过H类将代码切回到主线程中执行后续操作**
根Activity启动过程会涉及4个进程,分别是Zygote进程、Launcher进程、AMS所在进程(SystemServer进程)、应用程序进程。
*注:如果是普通Activity启动过程会涉及几个进程?答案是两个,AMS所在进程和应用程序进程。
本人是一个拥有6年开发经验的帅气Android攻城狮,记得看完点赞,养成习惯,微信搜一搜「 程序猿养成中心 」关注这个喜欢写干货的程序员。
另外耗时两年整理收集的Android一线大厂面试完整考点PDF出炉,资料【完整版】已更新在我的【Github】,有面试需要的朋友们可以去参考参考,如果对你有帮助,可以点个Star哦!
Github地址:【https://github.com/733gh/xiongfan】
Service的启动过程和Activity类似,它分为两个过程,分别是ContextImpl到AMS、ActivityThread启动Service。
Github地址:【https://github.com/733gh/xiongfan】