1.APP的启动流程
Zygote进程的创建
- APPRuntime
1.1 先来认识下zygote
什么是Zygote? Zygote是Android系统中特有的进程,不过说白了也只是名字特有而已, 言外之意,不多说了.总之我们先搞清楚一件事,Zygote一个最主要的作用,就是加快Android应用程序启动和运行速度.为什么这么说? 这就要知道Zygote进程在启动时做了什么.Zygote进程运行时, 会初始化Dalvik虚拟机,并运行它.Android的应用程序是由Java编写的, 它们不能直接运行在Linux上,只能运行在Dalvik虚拟机中. 并且, 每个应用程序都运行在各自的虚拟机中,应用程序每次运行都要重新初始化并启动虚拟机,这个过程会消耗相当长时间,是拖慢应用程序的原因之一.因此,在Android中,应用程序运行前,通过Zygote进程共享已运行的虚拟机的代码与内存信息,缩短应用程序运行所耗费的时间. 也就是说, Zygote进程会事先将应用程序要使用的AndroidFramework中的类与资源加载到内存中, 并组织形成所用资源的链接信息. 这样, 新运行的Android应用程序在使用所需资源时不必每次形成资源的链接信息, 这样就大大提升了程序的运行时间.所以我们知道了, 原来Zygote进程起到了预加载资源和类到虚拟机提高应用程序提高的作用
zygoteInit
JNI调用ZygoteInit的main()函数之后,Zygote进入了java 框架层,
public static void main(String args[]) {
...
try {
...
//注册Zygote用的Socket
registerZygoteSocket(socketName);//1
...
//预加载类和资源
preload();//2
...
if (startSystemServer) {
//启动SystemServer进程
startSystemServer(abiList, socketName);//3
}
Log.i(TAG, "Accepting command socket connections");
//等待客户端请求
runSelectLoop(abiList);//4
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
在main函数中,主要做了四件事:
- registerZygoteSocket(socketName);//1 用于接收ActivityManagerService发送创建的的应用进程的请求。
- 预加载
- 启动SystemServer进程。这是很重要的。
runSelectLoop
// 里面是一个死循环,用来执行创建新应用进程。
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
fds.add(sServerSocket.getFileDescriptor());//1
peers.add(null);
while (true) { // 死循环
StructPollfd[] pollFds = new StructPollfd[fds.size()];
for (int i = 0; i < pollFds.length; ++i) {//2
pollFds[i] = new StructPollfd();
pollFds[i].fd = fds.get(i);
pollFds[i].events = (short) POLLIN;
}
try {
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
for (int i = pollFds.length - 1; i >= 0; --i) {//3
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);//4
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
boolean done = peers.get(i).runOnce();//5
if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}
}
zygote 进程总结
zygote创建java世界的步骤
- 创建AppRuntime对象并调用其start方法,启动Zygote进程。以后得活动由APpRuntime来控制。
- 创建JavaVM并为JavaVM注册JNI.
- 通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层。
- 建立IPC服务通信–>通过registerZygoteSocket函数创建服务端Socket,并通过runSelectLoop函数等待ActivityManagerService的请求。
- 启动SystemServer进程。
- 预加载
- runSelectLoopMode创建
app的启动都干了些什么
Zygote孵化了第一个进程是system_server进程,而且孵化第一个App进程是Launcher,也就是桌面App。
-
launcher,也就是我们看到的桌面,在点击桌面app之后,发起进程就是Launcher所在的进程,启动远程进程,利用Binder发送消息给system_server进程;
-
在system_server进程中启动了N多服务,例如ActiivityManagerService(驻留在system_server中),WindowManagerService等。启动进程的操作会先调用AMS.startProcessLocked方法,内部调用 Process.start(android.app.ActivityThread);而后通过socket通信告知Zygote进程fork子进程,即app进程,进程创建后将ActivityThread加载进去,执行ActivityThread.main()方法。
-
在app进程中,调用
android.app.ActivityThread
main方法会实例化ActivityThread,同时创建ApplicationThread,Looper,Hander对象,调用attach方法进行Binder通信,looper启动循环。attach方法内部获取ActivityManagerProxy对象,其实现了IActivityManager接口,作为客户端调用attachApplication(mAppThread)方法,将thread信息告知AMS -
加载启动activity对象
-
加载View
-
布置屏幕
-
进行第一次绘制
参考文献
22.并行和并发区别
并发:一个处理器同时处理多个任务
并行:多个处理器或者是多核的处理器同时处理多个不同的任务.
前者是逻辑上的同时发生(simultaneous),而后者是物理上的同时发生
说完之后再试activity的启动流程
activity的启动主要的是分为三种情况
- 如果不存在应用进程,先创建应用进程。
- 当接受到启动 Activity 的调用时,使用 resolveActivity ,查询系统中符合要求的 Activity。
2 - 创建使用合适的 ActivityStack 和 launch flags 来启动 Activity
3 - 如果有activity存在就直接重启。