App的启动流程
Zygote 进程
Zygote 进程是整个Android系统的根进程,包括SystemServer进程和所有应用进程在内都是通过Zygote进程 fork 出来的。Zygote进程则是通过Linux系统init进程启动。
- 启动顺序:Linux系统的init进程–>Zygote进程–>SystemServer进程–>Application进程
- init进程:Linux加载完成之后会启动init进程,init进程会启动ServerManager,孵化一些守护进程,并解析init.rc孵化Zygote进程。
- Zygote进程:所有的App的进程都是Zygote进程fork出来的,包括SystemServer进程,Zygote初始化之后会注册一个等到接收消息的Socket,通过Socket进行IPC通讯。
App大致的启动流程:
- Launcher通过Binder进程间通讯机制(IPC)通知AMS启动一个Activity
- AMS通过Binder通知Launcher进入Paused状态
- Launcher通过Binder通知AMS已准备就绪进入Paused状态,然后AMS会利用Zygote.fork()创建一个新的进程,用于启动一个ActivityThread实例,即将启动的Activity就是在这个ActivityThread实例中进行的。
- ActivityThread通过Binder将一个ApplicationThread类型Binder对象传递给AMS,以便于AMS能够通过Binder对象和他进行通讯。
- AMS通过Binder进程间通讯通知ActivityThread,可以真正启动Activity了。
Activity的启动流程
https://blog.csdn.net/u012267215/article/details/91406211
- Launcher通知AMS要启动新的Activity(在Launcher所在的进程执行)
- Instrumentation工具类代为启动,最终调用到AMS的startActivity
- AMS先校验一下Activity的正确性,如果正确的话,会暂存一下Activity的信息。然后,AMS会通知Launcher程序pause Activity(在AMS所在进程执行)
- ActivityStackSupervisor.startActivityLocked :检查有没有在AndroidManifest中注册
- ActivityStack.startActivityLocked :判断是否需要创建一个新的任务来启动Activity。
- ActivityStack.resumeTopActivityLocked :获取栈顶的activity,并通知Launcher应该pause掉这个Activity以便启动新的activity。
- pause Launcher的Activity,并通知AMS已经paused(在Launcher所在进程执行)
- 主要通过ActivityThread的消息传递
- 检查activity所在进程是否存在,如果存在,就直接通知这个进程,在该进程中启动Activity;不存在的话,会调用Process.start创建一个新进程(执行在AMS进程)
- Process.start //在这里创建了新进程,新的进程会导入ActivityThread类,并执行它的main函数
- 创建ActivityThread实例,执行一些初始化操作,并绑定Application。如果Application不存在,会调用LoadedApk.makeApplication创建一个新的Application对象。之后进入Loop循环。(执行在新创建的app进程)
- 处理新的应用进程发出的创建进程完成的通信请求,并通知新应用程序进程启动目标Activity组件(执行在AMS进程)
- ActivityManagerService.attachApplication //AMS绑定本地ApplicationThread对象,后续通过ApplicationThreadProxy来通信。
- ActivityStack.realStartActivityLocked //真正要启动Activity了!
- 加载启动的Activity类,调用onCreate声明周期方法(执行在新启动的app进程)
- Instrumentation.newActivity //调用Instrumentation类来新建一个Activity对象,利用classLoder反射的方式
几个主要的类:
- ActivityStack:Activity在AMS的栈管理类,用于记录已经启动的Activity的先后关系和状态信息,通过ActivityStack决定是否启动新的进程。
- ActivityThread:ActivityThread 运行在UI线程(主线程),App的真正入口。
- ApplicationThread:用来实现AMS和ActivityThread之间的交互。
Activity的启动模式
- Standard:Task栈中不管是否存在都会在栈顶创建新的实例
- SingleTop:Task栈中栈顶是要启动的Activity则不会创建,如果不是则创建
- SingleTask:Task栈中存在要启动的Activity,则直接调用,并移除它之上的Activity实例
- SingleInstance:Task栈中只有一个activity实例
常见几个Flags:
- FLAG_ACTIVITY_NEW_TASK:将Activity放入一个新启动的Task
- FLAG_ACTIVITY_CLEAR_TASK:启动Activity时,将目标Activity关联的Task清除,再启动新Task,将该Activity放入该Task。该flags跟FLAG_ACTIVITY_NEW_TASK配合使用。
- FLAG_ACTIVITY_CLEAR_TOP:启动非栈顶Activity时,先清除该Activity之上的Activity。类似于SingleTop
设置FLAG_ACTIVITY_NEW_TASK的几种情况:
- 调用者不是Activity context
- 调用者是single instance
- 目标Activity带有singleInstance或SingleTask
- 调用者处于finishing状态
面试题:
- 一个app可以开启多个进程嘛,怎么做呢,每个进程都是在独立的虚拟机上嘛
- 可以开启多个进程,AndroidManifest.xml中的配置 android:process就可以实现
- 每个进程都是独立的
- 多进程可能存在的问题:比如Application内每个进程都会走到,可以根据进程分别进行初始化操作
- activity和service的通信方式
- 通过Binder对象:通过bindService的方式实现的时候,定义一个Binder实例,用于数据传输
- 通过Intent方式:
- 通过广播
- 谈谈Activity的四种启动模式,SingleTop和SingleTask启动模式的应用场