这些年带 Android 团队,越来越觉得“技术负责人”这个头衔的分量不在代码量,而在判断力。架构、性能、合规,这三座大山每个单拎出来都能写好几本书,但实际工作中它们往往是缠在一起的——你做了一个漂亮的组件化改造,结果某天合规扫描发现某个隐藏 SDK 在未声明的情况下拿走了 OAID;你费尽心思把启动耗时压进 1 秒,结果线上反馈某款低端机热启动反而变慢了。这篇文章我想把这三个维度的实战经验放在一起梳理,聊一些踩过坑之后才真正想明白的东西,希望能对正在往这个方向走的同学有点帮助。
1. 重新理解这个岗位:高级负责人到底在做什么
1.1 负责人与技术骨干的分水岭
很多人以为从“高级开发”到“技术负责人”是编码能力的进一步提升,代码写得越快越复杂就越配得上这个头衔。实际完全不是这么回事。我自己带团队的经验是:高级工程师的核心任务是把单点问题解决得漂亮,而负责人的核心任务,是让整个系统在无人时刻也能稳定运行、让团队里每个人都清楚自己那摊事情的边界、并且在各种限制条件下做出最不坏的选择。
这个转变最直观的体现就是:你不再有“把代码推翻重来”的权利。架构评审时你拍板用了某种方案,意味着你要为一年后线上出现的性能问题、合规风险、甚至是团队成员的维护成本买单。像 Android 这种迭代了十几年的老牌系统,又叠加了国内厂商定制 ROM 这个复杂环境,很多时候没有标准答案,只有权衡。
1.2 三个核心能力维度的权重判断
架构、性能、合规,这三个词在招聘 JD 里经常并列出现,但它们在负责人日常工作中的占比和性质完全不同:
- 架构解决的是“未来半年到两年”的问题。它影响的是扩展性、可维护性、团队协作效率。架构失误的代价不是立刻显现的,而是堆积到某个临界点后集中爆发。
- 性能解决的是“现在马上就能感觉到”的问题。用户不会看你代码写得多优雅,他们只关心 App 启动快不快、滑动跟不跟手、耗电高不高。性能问题直接左右留存和口碑。
- 合规解决的是“不能出事”的问题。它不像架构和性能那样能带来正向收益,但一旦触雷,轻则应用下架、重则涉及法律责任。在国内做 Android 生态,合规是 1,架构和性能是后面的 0。
我的感受是:架构能力决定团队能走多快,性能优化决定用户愿不愿意跟着走,合规意识决定你能不能安全到达终点。这三者需要按比例投入精力,任何一项偏废,都会在不远的将来变成事故。
2. 架构能力:在复杂的现状里做有约束的决策
2.1 客户端架构演进是一条被踩出来的路
如果说服务端的分布式架构是“把一件事拆到很多机器上做”,那么客户端的架构设计就是“把所有事情塞进一个进程里还要保持清爽”。Android 客户端架构演进到今天,大致走过了几个阶段:
- 早期 MVC:Activity/Fragment 既是 View 又是 Controller,代码一多直接变成 God Activity,几千行一个文件。
- MVP 与 MVVM:把界面逻辑和业务逻辑做分离,可测试性大幅提升。MVVM 配合 Jetpack 的 ViewModel 和 LiveData(现在更多是 StateFlow),成为目前国内团队的主流基线。
- MVI:强调单向数据流和不可变状态,在复杂交互页面和团队规范约束上非常有价值,但学习成本和样板代码也更高。
架构没有银弹,只有适不适合。我见过小团队硬上 MVI 导致每个页面都要写一堆 Reducer 和 Effect,反而拖慢了迭代速度;也见过大厂核心链路用 MVC 写得很克制,因为团队稳定、规范严格、Code Review 认真,一样可以健康运行。架构的本质是约束,而不是炫技。
2.2 模块化与组件化:边界意识比技术选型更重要
现在基本没有团队敢把一个几百万行代码的 App 做成单模块了。模块化和组件化成了标配,但很多人把“拆模块”本身当成了目标,拆完之后依赖乱成蜘蛛网,改一个底层库要连环编译八九个模块。
我理解的模块化核心是边界。业务模块之间不允许直接互相依赖,通过接口层下沉到基础能力层;共用能力放在独立的 library 模块里,但禁止从 UI 层反向依赖实现细节。用生活类比就是搬家:你收拾的不是“把东西塞进更多箱子”,而是“每个箱子贴清楚标签、规定哪些东西必须放哪个区域”,否则搬完家找锅都得翻一小时。
实操中我做过的比较好的约束是三层结构:
- App 壳层:只负责 Application 初始化、主流程编排、全局配置。
- 业务模块层:按功能域划分,比如登录、首页、订单,模块间通过路由和协议通信。
- 基础能力层:网络、存储、图片加载、埋点、崩溃监控等,被上层共用,但绝不允许反向依赖。
这种结构不新鲜,但真正难的是守住。我用过最有效的办法是:结合 Gradle 依赖约束(implementation 代替 api,强制禁止跨模块引用内部类),再在 MR 流水线里加依赖扫描脚本,凡是不符合分层规则的代码直接打回。靠自觉没有用,必须靠机制。
2.3 技术选型的决策模型:从“哪个好”到“哪个更适合”
负责人在架构上最常面对的坑,就是“技术选型变成舆论战”。今天团队里有人说 Coroutine Flow 比 RxJava 好,明天又有人说 Compose 要全面替换 View 体系,整个团队陷在工具比较里出不来。
我后来总结了一套选型框架,用来避免无休止的口水仗:
- 业务阶段匹配:项目处在快速试错期,就选团队最熟的技术,而不是最新的技术;处在稳定迭代期,才考虑用新方案解决存量痛点。
- 性能账要算明白:比如 Compose 的写法和 UI 效率确实现代,但低端机上的首次组合耗时和包体积增加是实打实的成本,需要评估你的用户机型分布。
- 团队学习成本:引入一个新技术,团队需要多久从“会用”到“会调优”?这期间出线上问题谁能兜底?
- 退出成本:万一这个方案推翻,迁移工作量有多大?
选完之后还要做的一件事:写架构决策记录(ADR)。把背景、备选方案、权衡过程、最终结论写清楚,避免三个月后新人又问“我们当初为什么不用 XX”。这件事听起来很虚,但在团队扩张期能省掉无穷无尽的重复讨论。
3. 性能优化:用可量化的体系替代感觉
3.1 先把北极星指标定下来
性能优化最怕的是一上来就“优化”。没有指标、没有基线,优化就是耍流氓。我见过团队花了两周去优化某页面掉帧,最后发现该页面日均 UV 不到三位数,而启动耗时同比劣化了 15% 都没人发现。
负责人要做的第一件事,是定下北极星指标。对大多数业务型 Android App 来说,我建议至少盯住这几个:
- 冷启动耗时:从点击图标到首页可交互的时间,建议分位数统计,而不是只报均值。
- 卡顿率:定义“慢帧率”,比如单帧渲染超过 700ms 即记为一次卡顿,按会话维度统计卡顿会话占比。
- 崩溃率与 ANR 率:不用多解释,这是用户体验的生命线。
- 核心页面交互延迟:比如首屏渲染完成时间、列表第一帧的响应速度。
指标定好之后,工具链就能围绕指标搭建。APM 领域市面上有不少成熟方案,开源的有微信的 Matrix,商业的有博睿、听云这些,如果团队有精力也可以自建,但我的建议是初期别重复造轮子,先用开源的把流程跑通,真正遇到数据采集不满足业务场景时再投入自研。
3.2 卡顿治理:别把所有问题都归到主线程
Android 性能优化最经典的话题就是卡顿。很多开发一提到卡顿就说是主线程做了耗时操作,这其实只对了一半。卡顿的本质是帧超时,也就是垂直同步信号到达时没有完成渲染。造成它的问题可能来自多个方向:
- 主线程 CPU 繁忙:复杂的布局计算、大量对象创建、死循环等。
- 渲染管线瓶颈:布局层级过深、过度绘制、GPU 负载过高。
- Binder 调用阻塞:频繁且大体积的跨进程通信,比如反复读取系统服务信息。
- 内存问题引发 GC 频繁:内存抖动导致 GC 频率上升,像垃圾回收时 STW(Stop-The-World)会直接造成帧停顿。
排查这类问题,我比较推荐的路线是先用 Matrix 的 TraceCanary 采集卡顿时的主线程调用栈,再结合 CPU Profiler 或 Perfetto 看时间片分布。这里插一句:Perfetto 是真的很值得花时间学,它能看到系统层面的调度信息,偶尔在复杂问题排查时能帮上大忙。
用生活类比理解这套排查思路就是:你先要知道水管是在哪个位置堵的,是源头水压不够(CPU 负载高),还是管道转弯太多(布局层级深),还是出口接了太多分支(过度绘制),而不是拿起锤子到处敲。
# 用 Perfetto 抓取 trace 后先看这几个关键区域: # - ftrace: CPU 调度 # - gfx: 帧生产与提交时间 # - binder_driver: Binder 调用耗时 # - surfacelinger: 合成耗时3.3 启动优化:每一毫秒都是抠出来的
启动耗时是用户对 App 的第一印象,也是性能优化里最能看到回报的战场。冷启动流程从 Application 的 attachBaseContext 开始,到首页 draw 完成,中间每一段都能挤出水来。
我们实操时把启动过程分成了三块来抠:
Application 初始化:把所有能在子线程做的初始化一律挪到子线程,核心原则是“不阻塞首帧和首屏数据请求的初始化优先级最高”。比如图片加载库、埋点 SDK、网络库的全局配置,能异步就异步。但要注意,部分 SDK 要求必须在主线程初始化,或者某些初始化之间存在隐式依赖,挪的时候要逐个验证。
首屏布局优化:第一帧渲染出来再填充数据,别把全部数据都等齐再显示。用异步布局或懒加载把首屏 View 的创建成本降下来,必要的时候可以用启动封面过渡,但不要用假闪屏骗人——启动封面盖住的是后面的加载过程,治标不治本。
任务调度编排:把启动任务梳理清楚后,用拓扑排序跑依赖关系,能并行的并行,能延后的延后。现在也有框架帮忙做启动器(比如阿里的 Alpha),但我觉得小团队没必要引框架,用简单的 Task 调度器就够。
注意:启动优化最大的坑是劣化不可见。很多优化在高端测试机上毫无感知,但到了用户真实的低端机上差别巨大。所以启动优化的验收必须建立在真实机型分位数上,有条件用众测平台找一批低端机做灰度对比。
4. 合规实战:从被动补救到主动设计
4.1 合规不是法务一个部门的事
Android 领域的合规问题,这些年被讨论得越来越多。每次应用商店通报一批违规 App,都能看到不少知名产品赫然在列。很多技术团队把合规当成法务的活,法务出文档、提要求,技术照着做,这是典型的被动合规模式,事后来看往往是要出事的。
我自己的经验是:合规必须前置到架构设计阶段。一个数据采集需求进来,不能先想怎么拿到数据,再想合不合法;而是应该先问“这个数据是不是真的必要”“能不能用更轻量的方式达到同样目的”。这就像盖房子的时候就要留好消防通道,而不是等验收之前再砸墙。
做技术负责人,至少要在三个层面把好关:
- 权限最小化:能用
ActivityResultContracts或更克制的方式就不申请敏感权限;能只在用户主动操作时临时申请,就不要在启动时申请一堆。 - 数据采集透明化:隐私政策里的说明必须和实际代码行为一致,这是基本红线。特别要小心第三方 SDK 的自采集行为,很多 SDK 不接隐私合规接口,装上之后就会悄悄收集设备信息。
- 本地化处理优先:很多信息根本不需要上报到服务器,在本地处理完只上报结果就行了。既保护用户隐私,也省流量省电,一举多得。
4.2 权限与数据采集的工程化落地
分享几个偏实战的工程化做法:
- 运行时权限申请统一收口:不要允许业务方在任意页面直接调用
requestPermissions,而是由一个权限管理模块统一申请、统一回调,同时记录申请路径和用户授权结果。这样合规审计时能说得清楚“我们在哪个环节、因为什么功能、申请了什么权限”。 - 设备标识符适配:IMEI 这类硬标识符在常规业务中早就不能碰了,连 READ_PHONE_STATE 权限都建议直接放弃申请。业务需要的设备唯一标识用 OAID、或者服务端下发的 UUID 就够了。而且要配好默认值逻辑,用户拒绝授权时也要能正常跑流程,不能因为拿不到标识符就弹崩溃或死循环重试。
- SDK 管控:每一款集成的 SDK 都要做数据安全评估,建议建立一个清单,包含 SDK 收集的信息类型、用途、隐私政策链接、合规对接状态。这个清单定期更新,新 SDK 没通过评估不允许接入代码。
4.3 合规与性能和体验的博弈
合规往往会给性能和体验带来“副作用”,这是无法回避的。典型场景是:合规要求首次启动弹窗让用户选择同意隐私政策,这个弹窗本身就会增加启动流程的变数;合规要求降低后台采集频率,结果运营想看的活跃数据变得不准确。
我遇到这类博弈时,处理原则是:安全底线不可退让,但实现方式要灵活。比如隐私政策弹窗展示和数据上报可以并行准备,用户同意前先把该加载的资源加载好,同意后再补充执行受限部分;后台数据采集频率限制后,就调整统计口径和分析模型,而不是想方设法绕过限制。技术负责人要能顶住业务那边的压力,明确告诉对方“这条路会带来下架风险,不能走”,同时给出替代方案——既坚持底线,也帮忙解决问题,这样团队才信任你。
5. 从执行者到负责人的软实力升维
5.1 把一个人会的事变成一群人会的事
架构和性能这些东西,最后都要落到团队身上才能真正变成组织能力。我见过很多技术很强的负责人,自己上手解决问题飞快,但团队其他人遇到类似问题还是两眼一抹黑,这就是典型的只做了“执行”没做“负责人”。
我现在比较坚持几件事:
- 设计评审必须开:新模块、大改动、跨端方案,上线前必须做设计评审。评审不是为了卡人,而是为了让更多人理解方案的上下文,也提前发现设计死角。
- Code Review 要有标准:不只看代码有没有 bug,还要看是否遵循了架构分层、有没有明显性能隐患、数据采集是否符合合规要求。这三个维度长期坚持,团队成长非常快。
- 沉淀文档和案例集:每次线上事故、每个典型性能问题、每次合规整改,都要求形成案例总结。这批知识库是团队真正的资产,比代码库还值钱。
5.2 跨团队协作的现实场景
Android 负责人在大公司里还免不了各种跨团队拉扯。产品想要一个数据验证功能,合规不允许采集;服务端希望客户端多传一些设备信息做风控,性能优化要求减少网络包体积。这些问题没有标准答案,你的价值就是在冲突中找到各方都能接受的折中方案。
我的经验是多问“为什么”,别急着说“不行”。比如产品要某个数据,先搞清楚背后的业务目标是什么,也许用已有的数据、换一种验证方式也能达到同样的效果。能真正理解对方目标并给出替代方案的人,才配叫负责人;只会拿着规范说“不能做”的人,本质上还是规范的工具人。
6. 写在最后的几句话
做 Android 技术负责人这几年,我最深的体会有两条。
第一条是:技术能力是入场券,不是护城河。架构、性能、合规这些专业技能当然要硬,但真正决定你在这个位置上能不能坐稳的,是你发现问题的敏锐度和做决策的质量。系统不会因为你辛苦就保证不崩,用户不会因为你加班就原谅卡顿,监管不会因为你不知情就免除处罚。所有好的结果,都来自于提前一步的思考和设计。
第二条是:这个岗位永远在学习和适应中。Android 系统每个版本都在收紧隐私和权限控制,应用商店规范每年都在更新,用户对 App 质量的要求只增不减。我有一个习惯,每半年专门抽一整天,什么代码也不写,只复盘过去这个周期里因为架构、性能、合规踩过的坑,把它整理成团队分享素材。这个习惯让我在很多问题引发事故之前,就有了预警意识。
如果你正在带 Android 团队,或者正努力站上这个岗位,希望这篇分享里的经验教训能帮你少走一些弯路。技术层面的东西都可以通过学习和训练补上,唯独要有意识地锻炼的是:当所有条件都模棱两可、没有标准答案的时候,你依然能够做出一个让大家愿意跟随你的决策。