Android应用启动流程(待细化)
冷启动就是在 Launcher 进程中开启另一个引用 Activity 的过程。这是一个 Launcher 进程和 AMS,应用进程和 AMS,WMS 双向通信的过程:
- Launcher 进程和 AMS 说:“我要启动Activity1”
- AMS创建出 Activity1 对应的 ActivityRecord 以及 TaskRecord,通知 Launcher 进程执行 onPause()
- Launcher 执行 onPause(),并告知 AMS
- 启动一个 starting window,AMS 请求 zygote 进程 fork一个新进程
- 在新进程中,构建ActivityThread,并调用main(),在其中开启主线程消息循环。
- AMS 开始回调Activity1的各种生命周期方法。
- 当执行到 Activity.onAttch()时,PhoneWindow 被构建。
- 当执行到 Activity.onCreate()时,setContentView()会被委托给 PhoneWindow,并在其中构建DecorView,再根据主题解析系统预定义文件,作为 DecorView 的孩子,布局文件中肯定有一个 id 为 content 的容器控件,他将成为 setContentView 的父亲。
- 当执行到 Activity.onResume()时,DecorView 先被设置为 invisible,然后将其添加到窗口,此过程中会构建 ViewRootImpl 对象,它是 app 进行和 WMS 双向通信的纽带。ViewRootImpl.requestLayout()会被调用,以触发View树自顶向下的绘制。
- View 树遍历,会被包装成一个任务抛给 Choreographer。在此之前 ViewRootImpl 会向主线程消息队列抛一个同步消息屏障。以达到优先遍历异步消息的效果。
- Choreographer 将任务暂存在链式数组结构中,然后注册监听下一个 vsync 信号。
- 待下一个 vsync 信号到来之时,Choreographer 会从链上摘取所有比当前时间更早的任务,并将他们包装成一个异步消息抛到主线程执行。
- 异步消息的执行,即是从顶层视图开始,自顶向下,逐个视图进行 measure,layout,draw的过程。
- ViewRootImpl 持有一个 surface,它是原始图形缓冲区的一个句柄,原始图形缓冲区是一块存放像素数据的内存地址,这块内存地址由app进程和SurfaceFlinger共享。当 app进程执行完上述步骤时,就意味着像素数据已经填入该块内存,于是 app 通知 SurfaceFlinger 像素数据已经就绪,可以进行合成并渲染到屏幕了。
- 当 DecorView 完成渲染后,就会被设置为 visible,界面展示出来。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 炎武的学习笔记!