Android Framework 新手学习踩坑建议指南

背景

很多学员刚开始都是从app或者其他技术栈转到安卓framework的学习,因为framework是安卓系统核心框架层面。代码量相当大,而且framework的相关核心工作都是需要去深入这些framework的模块代码进行相关的问题bug修复和需求实现。

那么新手学习到底容易踩哪些坑呢?具体又应该怎么正确深入学习framework呢?


坑一:试图记忆整个 AOSP 源码流程

错误大坑 --想要盲目分析代码细读每一行

打开一个模块(比如 AMS,ATMS,WMS),上来就自己逐行读代码,试图把每个方法、每个分支、每个变量都记下来,但是代码太多太复杂分支千千万万很容易发现自己分析的代码根本不是啥主线流程。结果就是发现自己学了一个月后啥也没有记住,啥也不会,什么framework知识都没有学到,也不具有一点fw的实战能力,以为fw学习就是学习源码就可以。

正确做法:理解核心脉络,理解性记忆

  • 先搭骨架,再填血肉。比如 AMS 的核心脉络是:进程启动流程、四大组件启动流程、进程调度(adj 算法)、ANR 机制。不在细枝末节上纠缠。
  • 理解"为什么"而不是"是什么" 。比如不要记 realStartActivityLocked 的代码,而是理解为什么 Activity 启动需要经过这么多步骤(进程检查、权限检查、生命周期同步、窗口准备......)。
  • 用一张图就够了:每个模块画一张核心概要图,剩下的细节用"索引式记忆"------知道是哪个类、哪个方法处理的,用到时能定位到即可。

理解清楚一些代码区分和进程区分概念:

要分析源码时候,尽量要搞清楚进程的运行,理解一下代码会运行在哪个进程。

framework代码有一些是公共框架代码,这种代码属于app和system_server都是共用的,比如Activity,Service,Configration等,这种framework的代码路径一般不会带有server,而一些属于system_server进程专属的代码比如ActivityManagerService,WindowManagerService等。


坑二:盲目学习源码,应该要以场景为目标进行分析串联

大坑表现

学习源码分析时候没有一个场景目标,盲目分析,随意的找一个类进行分析,比如很多同学可能会以startActivity为开始进行分析,但是分析过程中跳转流程分支太多太多,发现根本没有办法掌握,瞬间感觉自己进入了一个迷宫,或者说分析了很久代码,其实根本不是主线流程代码。导致自己只是在冰山的某个角落,而没有走到正确上山的道路。

源码是手段,分析问题、解决问题、产出需求才是目的。脱离问题场景看源码,就像背字典学英语------记住了单词,但不会说话。

所以源码太多,你不能什么代码都看,而是需要明确自己的需求模块,来有目的去分析看源码

正确做法:以需求场景或者bug为导向学习源码

  • 带着需求主线看源码 :比如初学者你完全可以以一个经常使用的场景作为分析的切入点,比如场景桌面点击app图标,是如何显示出第一帧Activity的画面,以这个为脉络流程的主线进行分析源码。

这样你分析桌面点击app图标时候,首先就会去深入触摸input子系统模块,对InputReader,InputDispatcher,再分析事件如何到达Launcher这个app的,这样你就很有成就感的理清楚了input事件的分发流程。

再接下来分析桌面的调用startActivity到AMS,分析AMS,ATMS,WMS,SurfaceFlinger相关复杂流程。

这样你有目的和场景的分析源码后,就会发现自己脑海中串联各个模块的代码时候就会变得很简单,这个就是典型的理解性记忆,是有目的场景的分析代码,这样主线脉络去学习你就很容易记住这些核心场景的源码主要是啥。


坑三:只会被动读代码,不会主动调试

新手大坑

只看不跑、只读不调。一个模块看了一星期,但一次 dumpsys 都没执行过,一次断点调试都没做过。

Framework 的代码运行在真实系统进程中(system_server 等),只看静态代码看到的只是冰山浮出水面的一角,大量的运行时行为(时序、状态机、Binder 交互)是读不出来的。

只看代码不调试追踪最重要的问题:

源码分析往往代码很多,你如果不找到合适的切入方法函数点进行堆栈打印反向调试追踪,基本上正向分析会很难很难,比如WindowState的remove移除方法,其实正面分析这个remove方法调用地方会有很多很多地方,单独源码分析,你根本无法知道具体是哪里调用过来的。

那么这个时候你的正向源码很可能是错误的。

还有正常系统是运行的状态,代码中的很多变量等都是最核心的数据,这些数据在源码分析时候你其实比较难知道是啥,所以这个时候就需要有一些dump工具辅助你直接确认数据。

正确做法:掌握调试三板斧

1. logcat 堆栈,日志打印 + 日志过滤分析

添加堆栈打印

bash 复制代码
        Log.i("lsm","onCreate",new Exception());

正常logcat第三个参数变成new Exception既可以。

给日志加过滤,不要盯着满屏日志看:

bash 复制代码
# 只看 AMS 相关标签
adb logcat -s ActivityManager

# 看系统进程的详细日志并保存到文件
adb logcat -b all -v threadtime > trace.log

也可以考虑马哥课程中的wms讲解的Proto相关日志动态开放来辅助你调试

2. dumpsys------查看运行相关模块的核心数据

正常系统是运行的状态,代码中的很多变量等都是最核心的数据,这些数据在源码分析时候你其实比较难知道是啥,所以这个时候就需要有一些dump工具辅助你直接确认数据。

几乎所有系统服务都实现了 dump() 方法,这是观察系统运行时状态的最快方式:

bash 复制代码
# 看 Activity 栈状态
adb shell dumpsys activity activities

# 看窗口状态
adb shell dumpsys window windows

# 看电池/唤醒锁
adb shell dumpsys batterystats

# 看所有服务的 dump 入口
adb shell dumpsys -l
3. Android Studio 断点调试 system_process

这是学习新模块最有效的方法:

  • Attach Debugger 到 system_process
  • 在你感兴趣的方法上打断点
  • 触发操作,观察调用栈、变量值、线程状态
  • 单步跟踪不用全流程走完,走 5-10 步就能理解关键逻辑
4. trace 分析(进阶)

也可以采用Perfetto方式进行源码流程追踪,系统在核心方法部分都会埋点Trace打印,自己可以可以对代码进行加入,这样展示出相关slice方便查看和调试。

bash 复制代码
cat config.txtpb | adb shell perfetto -c - --txt -o /data/misc/perfetto-traces/trace.pftrace
# 抓 systrace/perfetto 看时序
# 用 perfetto UI 或 systrace.py 打开

学一个模块的正确姿势是:看 20 分钟代码 → dump 看看现状 → 断点跑一遍关键路径 → 总结出一张图。 而不是看三天代码不动手。


坑四:缺少framework实战项目能力

表现

花大量时间阅读源码、画流程图,感觉很充实;但遇到实际问题时一头雾水,不知道从哪下手。

能把四大组件的启动流程画得非常漂亮,流程图、时序图、UML 应有尽有。但分配一个真实需求(比如"实现一个 API 让三方应用可以限制某个 Activity 的最大启动次数"),立刻卡住,不知道从哪改起。

画图是"信息的整理",写代码是"系统的干预"。你能看懂一个系统,和你能修改一个系统,是两种完全不同的能力。

正确做法:用真实的 Framework 定制需求来驱动

以下是结合实际工作/学习场景的实战路径,覆盖 Framework 最核心的几块定制改造:

1 Input 系统实战,input需求及疑难ANR的分析

2 AMS 闪屏/黑屏/部分黑/闪白问题实战,疑难显示问题

3 WMS 窗口管理实战,查看定制等

4 车载多屏互动实战

5 分屏 / 自由窗口定制实战

这些实战都在马哥framework实战课程和学员作业中有进行详细的讲解。

总结

framework的学习终极目标不是源码分析,而是进行安卓系统的需求定制和疑难问题的实战解决,但是源码分析属于需求和bug解决实现的最重要的理论基础。

所以源码分析也是一样很重要,源码分析提供了理论基础后,更重要是利用这个理论基础再结合各种调试和分析工具等来帮助我们解决实际需求和问题。


原文地址:

https://mp.weixin.qq.com/s/U68r33rGmUAZq08g2Lf2tA

更多framework实战开发入门学习干货资料,请关注下面"千里马学框架"

相关推荐
我命由我123453 小时前
执行 Gradle 指令报错,无法将“grep”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
狂奔solar4 小时前
ARMA 模型:从白噪声到万能逼近器
android
渣渣灰飞5 小时前
MySQL 系统学习 第五阶段:企业级 MySQL 实战开发 第二章:RBAC 权限系统设计
android·学习·mysql
qq_422828625 小时前
android 图形学之图层数据送显及合成图层(七)
android
天若有情6736 小时前
前端性能优化:从“按下预加载”到“AI级智能预判系统”
前端·性能优化·js·active·hover·首屏加载
MiyamuraMiyako6 小时前
Compose:从自动滚动到双锚点 LazyLayout
android·android jetpack
yyt3630458417 小时前
KlineChartQuant Tooltip 高频交互 200FPS 性能优化完整复盘
前端·经验分享·性能优化·typescript·vue·交互·chrome devtools
青枣八神8 小时前
Expo如何只通过数据线连接手机的Expo go
react native·智能手机·安卓
用户63421419935078 小时前
base_logger_core --- 跨平台 C++ 日志核心库
android