Moosphan/Android-Daily-Interview

2019-04-09:请简述从点击图标开始app的启动流程?

Moosphan opened this issue · 7 comments

2019-04-09:请简述从点击图标开始app的启动流程?

我来简单的说下吧:
热启动:后台还存活,这时点击图标不会走application生命周期方法,直接初始化activity及其生命周期方法。
冷启动:先初始化application,依次执行attachedbasecontext,oncreate,然后走activity生命周期方法。欢迎大佬进行详细的补充哈

1.点击app图标,Launcher进程使用Binder IPC向system__server进程发起startActivity请求;
2.system__server进程收到1中的请求后,向zygote进程发送创建新进程的请求;
3.zygote进程fork出新的App进程
4.App进程通过Binder IPC向system__server进程发起attachApplication请求;
5.system__server进程收到4中的请求后,通过Binder IPC向App进程发送scheduleLauncherActivity请求;
6.App进程的ApplicationThread线程收到5的请求后,通过handler向主线程发送LAUNCHER_ACTIVITY消息;
7.主线程收到6中发送来的Message后,反射创建目标Activity,回调oncreate等方法,开始执行生命周期方法,我们就可以看到应用页面了。

  1. startActivity到AMS
  2. AMS发送创建进程的请求到Zygote进程
  3. Zygote进程fork一个新进程
  4. 创建完进程,AMP(ActivityManagerProxy)发送attachApplication请求到AMS
  5. AMS执行realStartActivityLocked启动Activity
  6. ApplicationThreadProxy发送scheduleLaunchActivity到App进程的ApplicationThread
  7. 通过handler发送Launch Activity消息来启动Activity
  8. ActivityThread就可以开始OnCreate

点击图标后,Launcher向AMS请求打开Activity
如果没有可用的缓存进程,AMS会向zygote请求创建新进程
zygote使用fork()创建进程并设置好,随后进入ActivityThread的main(String[] args)方法
ActivityThread初始化Looper,Handler等,随后进入死循环等待由AMS发来的消息
AMS发送消息,让应用程序回调各组件的生命周期

  1. 点击图标后Launcher进程会通过Binder机制向AMS发起打开Activity的请求【IPC->Binder】
  2. AMS会通过ActivityStarter处理Intent和Flag(启动模式相关的内容),然后通过Socket通知zygote进程【IPC->Socket】
  3. zygote进程会进行孵化(虚拟机和资源的复制),然后fork出新进程
  4. 然后zygote进程会通过invokeDynamicMain()方法调用到ActivityThread的main方法【ActivityThread】
public static void main(String[] args) {
    // 1. mainLooper
    Looper.prepareMainLooper();
    // 2. 创建ActivityThread,执行attach
    ActivityThread thread = new ActivityThread();
    thread.attach(false);
    // 3. Handler
    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }
    // 4. loop()
    Looper.loop();
}
  1. main()中关于Handler相关的工作是:主线程Looper和Handler的创建、开启主线程Looper的消息循环
  2. main()另一工作就是创建ActivityThread对象,执行attach方法。【Application、ContentProvider】
  1. 先通过AMS执行bindApplication方法
  2. 内部会创建属于Application的ContextImpl对象,并且创建Application对象,建立两者的联系
  3. 创建ContentProvider,执行其onCreate()方法,并进行发布相关操作(前提是该app有ContentProvider)
  4. 执行Application的onCreate()方法

知识点要建立体系,上面【】部分就是扩展的点。
比如:

  1. 进程间通信IPC的Binder机制有哪些应用的场景?
  2. IPC中Socket方式有哪些应用场景?
  3. Application的Context上下文对象是在哪里初始化的?
  4. ContentProvider是在哪里创建、初始化和发布的?
  5. ContentProvider的onCreate()和Application的onCreate()方法哪个先执行?

这些东西都能从App启动流程中找到答案,还有很多扩展的点,就不多说了。上面attach()方法的源码细节也很多,也不赘述了。

点击图标 Launcher 会向 binder方式 systemserver 中的activitymanagerservice(ams) 请求startactivity
ams 收到信息后 通过 socket 方式 联系 zygote进程, zygote 进程fork自身 创造出app进程
app进程的ActivityThread main方法开始执行 在ApplicationThread 中初始化application ,再bindapplication,并且向AMS(binder方式) 通知 application创建完毕,
AMS 向App进程(binder)调用 scheduleLaunchActivity ,ActivityThread会调用 performLaunchActivity, 调用 Activity的 newInstance方法(反射) 构造出 Activity实例,
最后走 Activity的 oncreate onresume onstart

推荐一篇优秀的文章
Activity启动流程源码分析