当前位置: 首页 > article >正文

【Android 源码分析】Activity短暂的一生 -- 目录篇 (持续更新)

1. 前言

忽然有一天,我想要做一件事:去代码中去验证那些曾经被“灌输”的理论。
                  
                  
                                           – 服装学院的IT男

从事多年App开发现转Framework,由于对WMS感兴趣,所以决定以"桌面点击应用图标,到应用的Activity显示到屏幕上"这一简单操作为基础,分析整个过程。

整个流程看起来似乎并不复杂,整个操作过程在手机上大概2秒就完成了,但是从零开始研究完整个流程,可能需要1年以上的时间。因为实际上涉及到了很多模块比如AMS,WMS,View系统,甚至还有SurfaceFlinger。

本着要把“Activity短暂的一生” 吃透的原则,决定投入自己一年的闲暇时间来把这2秒钟发生的事情搞个明白。

有些同学是应用开发或者是framework其他模块的开发,没有时间和精力来跟这些流程,所以我将研究的过程以博客笔记的形式分享出来,感兴趣的同学可以一起进步。

最近在看机会,上海同学公司如果有招人的名额可以私信或者在文章末尾加V联系我,感谢~

2. 文章归纳

在这里插入图片描述
整个操作的流程就是这样,目前判断整个流程涉及到以下几个模块(持续更新)。

在这里插入图片描述

    1. 主流程:应用冷启动的主要流程,比如Activity启动流程,窗口的添加显示
    1. 其他流程:基于整个主流程,还有很多核心的细节流程,比如窗口动画,生命周期等,这一块的数量会持续增加
    1. 知识拓展:比如在整个主流程,肯定会涉及到应用的绘制,还有SurfaceFlinger相关的处理
    1. 灵活一问:无论是面试,还是开发中,总会遇到一些问题,这部分将结合上面的流程针对问题做更详细的解释

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. 学习过程中的心得与踩坑

    1. Google团队一直在更新代码,有的模块甚至会被重构,所以看代码的时候不要想着记住每一行源码。
    1. 代码只是一些设计和思想的实现,对于分析源码,最重要的是理解设计思想,最好是能根据代码逻辑画出对应的流程图或者框架图。

tips:我以前在公司写App的时候,写代码之前是需要写《软件设计文档》的,文档评审过了才能根据文档进行代码的编写。现在是反过来看google的代码,那就是要做 “代码–>设计文档” 。 分析出整个google对于流程的设计文档倒是也不至于,但是设计思想,和模块框图,逻辑流程图还是需要尽量分析出来。这样也能加深印象,毕竟代码是枯燥的。

    1. 有条件的最好是下载AOSP编译,这样可以debug执行逻辑,另外还可以通过加log, 加堆栈的方式看执行逻辑,能极大的提高分析效率。
    1. 条件不允许的可以通过AS看到常见类的源码(能debug部分逻辑),或者去 google 源码的网站 https://cs.android.com/ 看(需梯子)。
    1. 看博客看书或者看视频学到的东西只是简单的了解,当然也是学习的第一步,第二步是需要总结记录相关的知识点,第三步如果能以自己的方式来把知识点讲出来,并且别人也能听得懂才是真正的掌握了这个知识点。
    1. 对于一个陌生的领域,学习是枯燥的,所以最重要的是对这块有兴趣,另外就是耐心。不要心急,踏踏实实学好一个知识再去学下一个,知识是互通的,前期会很慢,当自己的知识网构建好了,后面的学习的进度就会很快。
    1. 学习的时候放下其他的东西,特别是不要一边看书(视频)一边刷抖音,或者时不时打开下微信,然后还自己骗自己在学习,以为一个章节(视频)看完了就是学会了。个人的经历就是喜欢开着30分钟视频学习,然后动不动就分心打开下微信,然后心里着赶紧看完就是学完了,以为自己在30分钟做了几件事,是赚到了,是合理利用时间,其实最后会发现自己浪费了这30分钟,然后还要再花30分钟来重新看视频,本来半个小时学完就可以去玩游戏了,实际上花了1个多小时。
    1. 笔记很重要,但是也不能以为笔记记好了就等于会了。我记笔记是在学校读书养成的习惯,我刚入行的时候看《Android开发艺术探索》这本书的,因为对内容不理解但是又想记笔记,结果就是看完一遍其实没学会多少东西,但是记了很多漂亮的笔记,笔记的内容也基本上和书上的内容一模一样。这样最后我的学习变成了 :把书上的东西打字到我的笔记上,然后我告诉我自己,我学会了。但是实际上呢? 我啥也不会。
    1. 多问自己一些问题,过程中如果发现某个点自己不明白的,需要花时间去搞懂,不能“放过它”,相信我在研究的过程中会有意外的收获,而且能加深自己的理解。(当然一些不重要,或者难度极大的就没必要抓着不放了)
    1. 要有自信, 工作这么多年发现其实大部分人的智商都差不多,只要能静下心花时间去钻研就能领先于大部分人,身边的大佬们也是一步一个脚印走过来的。

4. 共勉

上山的路总是坎坷的,若有不对的地方或者什么宝贵的建议请及时指出。
学习最快的方式是相互探讨,若有志同道合的朋友愿意一起进步可以联系我。 (只要是Android方面的知识我都很感兴趣,无论是App开发还是WMS相关)
若有刚入行或者准备入行的小伙伴感到迷茫的,也可以一起沟通,一起壮大Android开发的队伍。


http://www.kler.cn/a/325925.html

相关文章:

  • 游戏引擎学习第14天
  • Ubuntu 22.04.4 LTS + certbot 做自动续签SSL证书(2024-11-14亲测)
  • 微信小程序之路由跳转传数据及接收
  • 【数据结构与算法】查找
  • vue2+3 —— Day5/6
  • 【MySQL】MySQL的笛卡尔积现象是什么?简单说说
  • 记一次教学版内网渗透流程
  • Proteus如何添加数码管
  • [遇到问题] Word中插入公式横线“-”变成了长连字符
  • 匿名管道 Linux
  • 2024年软考网络工程师中级题库
  • 汽车总线之----J1939总线
  • elementUI表格中某个字段(state)使用计算属性进行转换为对应中文显示
  • 【Linux】进程周边之优先级、调度与切换
  • 9.29总结
  • linux 命令行删除 整个单词
  • 【QT Quick】基础语法:导入外部QML文件
  • Linux之Docker虚拟化部署
  • STM32移植RT-Thread实现DAC功能
  • Go版数据结构 -【4.1 二叉树】
  • 1688商品API接口:电商数据自动化的新引擎
  • JVM 几种经典的垃圾收集器
  • 解决跨域问题的方法
  • Linux 网络配置 (深入理解)
  • 初识C语言(四)
  • Llama 3.2——同时具备文本和图像处理功能的开源模型