【Android 源码分析】Activity短暂的一生 -- 目录篇 (持续更新)
1. 前言
忽然有一天,我想要做一件事:去代码中去验证那些曾经被“灌输”的理论。
– 服装学院的IT男
从事多年App开发现转Framework,由于对WMS感兴趣,所以决定以"桌面点击应用图标,到应用的Activity显示到屏幕上"这一简单操作为基础,分析整个过程。
整个流程看起来似乎并不复杂,整个操作过程在手机上大概2秒就完成了,但是从零开始研究完整个流程,可能需要1年以上的时间。因为实际上涉及到了很多模块比如AMS,WMS,View系统,甚至还有SurfaceFlinger。
本着要把“Activity短暂的一生” 吃透的原则,决定投入自己一年的闲暇时间来把这2秒钟发生的事情搞个明白。
有些同学是应用开发或者是framework其他模块的开发,没有时间和精力来跟这些流程,所以我将研究的过程以博客笔记的形式分享出来,感兴趣的同学可以一起进步。
最近在看机会,上海同学公司如果有招人的名额可以私信或者在文章末尾加V联系我,感谢~
2. 文章归纳
整个操作的流程就是这样,目前判断整个流程涉及到以下几个模块(持续更新)。
-
- 主流程:应用冷启动的主要流程,比如Activity启动流程,窗口的添加显示
-
- 其他流程:基于整个主流程,还有很多核心的细节流程,比如窗口动画,生命周期等,这一块的数量会持续增加
-
- 知识拓展:比如在整个主流程,肯定会涉及到应用的绘制,还有SurfaceFlinger相关的处理
-
- 灵活一问:无论是面试,还是开发中,总会遇到一些问题,这部分将结合上面的流程针对问题做更详细的解释
2.1 主线任务(主流程)
google 为了方便窗口管理,新增窗口层级的概念,所以第一步需要了解这个是什么东西。
窗口层级相关:
WindowContainer窗口层级-1-初识窗口层级树
WindowContainer窗口层级-2-构建流程
WindowContainer窗口层级-3-实例分析
WindowContainer窗口层级-4-Layer树
既然整个主流程是以桌面点击图标启动应用分析的,所以Activity启动流程是基础,后续的分析都是基于这个启动流程的。
Activity启动流程:
Activity启动流程-1
Activity启动流程-2
Activity启动流程-3
Activity启动后并不代表屏幕上就有UI了,真正的图像显示需要在SystemService端添加窗口并绘制显示。
窗口显示三部曲:
首先需要创建窗口并将其挂载到将窗口树上
[窗口显示第一步-addWindow-1]
[窗口显示第一步-addWindow-2]
所以第二步计算出窗口的尺寸信息,传递给应用端,另外绘制View需要一个Surface,也是在这一步进行创建的
[窗口显示第二步:relayoutWindow -1]
[窗口显示第二步:relayoutWindow -2]
第二步执行完后,应用就开始绘制了,应用绘制完毕,需要把绘制内容显示到屏幕上,就需要触发finishDrawing流程
[窗口显示第三步:finishDrawingWindow]
执行完上面的这些流程后,屏幕上就有内容了,主流程就算完毕了。
窗口移除:
[removeWindow]
2.2 支线任务(其他核心流程)
基于整个主流程,还有很多核心的细节流程,比如窗口动画,生命周期等,这一块的数量会持续增加
Activity生命周期:
工作中分析问题,还是应用开发,都需要了解 Activity 的生命周期
-
[Activity生命周期之onPause]
-
[onCreate,onStart,onResume-1]
-
[onCreate,onStart,onResume-2]
-
[Activity生命周期之onSto1-1]
-
[Activity生命周期之onSto1-2]
-
[Activity生命周期之onDestory]
屏幕旋转:
-
[屏幕旋转-1]
-
[屏幕旋转-2]
-
[屏幕旋转-3]
窗口相关:
-
[桌面启动应用的视觉总结]
-
[应用启动动画-app_transition-1]
-
[应用启动动画-app_transition-2]
-
[应用启动动画-app_transition-3]
-
[应用启动动画-app_transition-4]
-
[StartWindow-SplashScreen-1-添加](
-
[StartWindow-SplashScreen-2-移除]
-
[应用窗口显示动画-starting_reveal]
ShellTransitions相关:
-
[ShellTransitions总体流程介绍]6
-
[ShellTransitions-1-同步组初始化]
-
[ShellTransitions-2-requestStartTransition处理]
-
[ShellTransitions-3-动画前准备]
-
[ShellTransitions-4-播放动画与结束处理]
2.3 知识拓展
2.3.1 SurfaceFlinger系统
毕竟显示端的控制还是在SurfaceFlinger中,虽然主要目的还是了解WMS,但是难免会接触到SurfaceFlinger,所以拓展部分主要就是SurfaceFlinger相关的知识。
- 屏幕显示基本原理
- Surface系统
应用端想要与 SurfaceFlinger 通信肯定是一个跨进程操作,源码的设计是通过 SurfaceSession
[Surface系统-1-应用与SurfaceFlinger建立链接]
应用端在 relayoutWindow 流程会创建 SurfaceControl 和 Surface,先介绍 java 层的创建逻辑
[Surface系统-2-SurfaceControl的创建(java层)
native 创建 SurfaceControl 和 Layer
[Surface系统-3-SurfaceControl的创建(native层)]
BLASTBufferQueue 的生产者消费者模型介绍
[Surface系统-4-BLASTBufferQueue和Surface的创建]
简单介绍 BLASTBufferQueue 的生产者消费者模型的工作流程,主要是对4个 buff 的处理方法分析
[Surface系统-5-BLASTBufferQueue工作流程概览]
- VSync 相关
- SurfaceFlinger的合成
2.3.2 View系统
- 测量
- 布局
- 绘制(软绘,硬绘)
- 事件分发
2.4 通用方法(模块)设计
记录一些高频率出现的方法或者模块设计,google 设计了一些方法在各个场景都会被调用,如果放在主流程分析则会增加阅读理解难度。所以提取出来抛开某个业务来分析会更加容易理解。
[BLASTSyncEngine设计剖析]
2.5 灵活一问
无论是面试,还是开发中,总会遇到一些问题,这部分将结合上面的流程针对问题做更详细的解释,这部分的问题,可能来自于高频率的面试题,也有我自己脑子里忽然冒出来的疑问,当然如果读者有感兴趣的问题也可以留言。
3. 学习过程中的心得与踩坑
-
- Google团队一直在更新代码,有的模块甚至会被重构,所以看代码的时候不要想着记住每一行源码。
-
- 代码只是一些设计和思想的实现,对于分析源码,最重要的是理解设计思想,最好是能根据代码逻辑画出对应的流程图或者框架图。
tips:我以前在公司写App的时候,写代码之前是需要写《软件设计文档》的,文档评审过了才能根据文档进行代码的编写。现在是反过来看google的代码,那就是要做 “代码–>设计文档” 。 分析出整个google对于流程的设计文档倒是也不至于,但是设计思想,和模块框图,逻辑流程图还是需要尽量分析出来。这样也能加深印象,毕竟代码是枯燥的。
-
- 有条件的最好是下载AOSP编译,这样可以debug执行逻辑,另外还可以通过加log, 加堆栈的方式看执行逻辑,能极大的提高分析效率。
-
- 条件不允许的可以通过AS看到常见类的源码(能debug部分逻辑),或者去 google 源码的网站 https://cs.android.com/ 看(需梯子)。
-
- 看博客看书或者看视频学到的东西只是简单的了解,当然也是学习的第一步,第二步是需要总结记录相关的知识点,第三步如果能以自己的方式来把知识点讲出来,并且别人也能听得懂才是真正的掌握了这个知识点。
-
- 对于一个陌生的领域,学习是枯燥的,所以最重要的是对这块有兴趣,另外就是耐心。不要心急,踏踏实实学好一个知识再去学下一个,知识是互通的,前期会很慢,当自己的知识网构建好了,后面的学习的进度就会很快。
-
- 学习的时候放下其他的东西,特别是不要一边看书(视频)一边刷抖音,或者时不时打开下微信,然后还自己骗自己在学习,以为一个章节(视频)看完了就是学会了。个人的经历就是喜欢开着30分钟视频学习,然后动不动就分心打开下微信,然后心里着赶紧看完就是学完了,以为自己在30分钟做了几件事,是赚到了,是合理利用时间,其实最后会发现自己浪费了这30分钟,然后还要再花30分钟来重新看视频,本来半个小时学完就可以去玩游戏了,实际上花了1个多小时。
-
- 笔记很重要,但是也不能以为笔记记好了就等于会了。我记笔记是在学校读书养成的习惯,我刚入行的时候看《Android开发艺术探索》这本书的,因为对内容不理解但是又想记笔记,结果就是看完一遍其实没学会多少东西,但是记了很多漂亮的笔记,笔记的内容也基本上和书上的内容一模一样。这样最后我的学习变成了 :把书上的东西打字到我的笔记上,然后我告诉我自己,我学会了。但是实际上呢? 我啥也不会。
-
- 多问自己一些问题,过程中如果发现某个点自己不明白的,需要花时间去搞懂,不能“放过它”,相信我在研究的过程中会有意外的收获,而且能加深自己的理解。(当然一些不重要,或者难度极大的就没必要抓着不放了)
-
- 要有自信, 工作这么多年发现其实大部分人的智商都差不多,只要能静下心花时间去钻研就能领先于大部分人,身边的大佬们也是一步一个脚印走过来的。
4. 共勉
上山的路总是坎坷的,若有不对的地方或者什么宝贵的建议请及时指出。
学习最快的方式是相互探讨,若有志同道合的朋友愿意一起进步可以联系我。 (只要是Android方面的知识我都很感兴趣,无论是App开发还是WMS相关)
若有刚入行或者准备入行的小伙伴感到迷茫的,也可以一起沟通,一起壮大Android开发的队伍。