版本说明(2026-10-13 核查):本文写于 2018 年。文中的机型、应用体验和厂商评价保留为当时的个人观察,旧硬件排名与购机建议已过期。下文修正技术错误,并补充 Android 10/12/13 等版本的变化;没有把历史体验当成当前版本的实测。
最近一直想写一些关于 Android 系统流畅度的东西,因为流畅度这个东西,是消费者最直接能体验到的,再加上 Android 一直为人诟病的越用越卡顿,使得大家在提到安卓机的时候,都会有一丝阴影。这也是大部分人买手机首先会考虑 iPhone 的一个原因。
由于 Google 对 Android 持开放态度,各个手机厂商生产不同产品定位的机器,以及各个 Android 应用的质量良莠不齐,导致影响 Android 流畅度的因素非常非常多,并非大家简单的以为是系统没有优化好,很多时候你会发现,不同 SOC 但是相同的系统,体验完全就是两种。
所以我想和大家聊聊影响 Android 系统流畅性的一些原因,后续大家遇到卡顿的问题,也不会单纯把锅甩给系统,或许你卸载一个 App 就解决了呢.
我想从下面几个方面展开聊这个话题:
- 硬件层面
- 系统层面
- 应用层面
- 流畅度优化闭环
准备好了,那就开始吧,欢迎你加入讨论
1. 硬件层面
CPU
CPU 是影响手机响应速度的重要器件。主线程处理业务、布局计算等工作都需要 CPU,但整机体验还取决于 GPU、存储、内存、散热和软件负载,不能只靠 CPU 判断手机档次。
原文按“高通 > 华为 > 三星 > 联发科”排列厂商,没有限定芯片型号、任务和测试条件,这个排名不能成立,也不适合作为今天的购机参考。比较时应落到具体 SoC 和整机,区分短时性能与持续负载下的表现。
GPU
各个厂商提供的 SoC 里面,通常包含了 CPU 和 GPU,例如 Snapdragon 845 搭配 Adreno 630。同一 SoC 的整机表现仍会受散热和功耗策略影响。
GPU 的能力会影响图形负载较重的应用和游戏,例如原文提到的《绝地求生:刺激战场》《崩坏 3》和赛车游戏。不过,不能只凭游戏名称判断它“吃 CPU”还是“吃 GPU”;《王者荣耀》也会随版本、场景、画质和目标帧率变化,需要看具体帧的 CPU/GPU 耗时。
Ram
2018 年写这篇时,4 GB 已经很常见了,旗舰没个 6 GB 或 8 GB,都不好意思说自己是旗舰。这是当时的市场观察和一句调侃,不能当成今天 Android 的最低要求或购机标准。
更大的 RAM 容量可以让系统以空间换时间:保留更多缓存进程和文件,减少重新加载。但容量不等于带宽,也不意味着可以无限放宽虚拟机堆、渲染缓存或预加载上限。缓存要有边界,是否变快仍取决于命中率、内存压力和实际负载。
当然如果后台进程多了又没有管住在后台跑,那么又会很耗电,有点得不偿失,这也是为什么国内的系统都会对进程管理这一块进行魔改。
UFS && EMMC
UFS 和 eMMC 都是移动设备常见的存储标准。原文讨论的是 2018 年常见的 eMMC 5.1 和 UFS 2.1,旧科普可参考这篇文章。
存储性能会影响文件读取、安装和资源加载,但接口名称不能独自决定应用流畅度,还要看随机读写、延迟、芯片实现和当前 I/O 负载。顺序拷贝快,也不代表所有启动场景都同样快。
原文“骁龙 660 不支持 UFS”的说法有误:高通 Snapdragon 660 官方产品资料明确列出 eMMC 和 UFS。平台支持与某款手机实际采用哪种存储是两件事,应查具体机型配置。
屏幕分辨率
1920 × 1080 是一种常见的 16:9 分辨率;不同长宽比的手机,不能都用这个数值概括“1080P”。更高的实际渲染分辨率通常意味着更多像素工作,可能增加渲染、合成、截图或录屏的带宽和计算成本;增加多少,要看实际渲染尺寸、硬件加速路径和瓶颈。
降低渲染分辨率可以减轻某些负载,但物理屏幕分辨率、应用渲染分辨率和录屏输出分辨率也可能不同。当年我拿魅族 MX4 Pro 举例,是因为有用户反馈它又卡又耗电;但单凭这些反馈,无法把原因全部归到 2K 屏幕上。
电池大小
电池容量会影响续航和整机设计,但续航还取决于屏幕、芯片效率、负载和温度;不同电压的电池也不能只比较 mAh。大电池本身不保证持续性能更好。
原文推荐 Oppo Find X、Vivo NEX、华为 Mate 10,是 2018 年的选购建议,现在已过期。保留这个例子,是想说明选手机时还要考虑实际使用时长和整机散热。
SoC 平台
SoC 的全称是 System-on-a-Chip。除了我们之前说的 CPU、GPU,还有其他功能模块,原文引用的科普见这篇文章,这里就不展开讲了。
SoC 是整个手机最重要的部分,是一切体验的基础。现在高通、三星、MTK 给手机厂家提供的硬件就是 Soc ,以及其配套的 Android 适配系统。手机厂商拿到这个之后,在其基础上做整机的设计,系统这边会在配套的 Android 适配系统上做移植,也就是把各家系统差异化的东西移植到新系统上。
按我在 2018 年接触高通、三星、MTK 适配系统的经验来看,高通提供的适配系统是功能最完善的,高通在 AOSP 的基础上,加上了高通自己的非常多的优化代码,并提供了完善的参数供手机厂商去配置,整体看开发起来是很舒服的,本身系统的问题不会太多,加上高通的文档完善,支持速度快,国内那么多手机厂商都在用高通也就不足为奇了。
这段评价来自当年的开发经历,没有提供统一对比测试,不代表这些厂商今天各平台的质量排序。
至于专利费,该给的要给啊。
我们经常会说,如果魅族早点用高通的 Soc,早 TM 上市了。
2. 系统层面
应用的管控策略
大部分 Android 应用开发者对国内的手机厂商恨的咬牙切齿,最大的原因就是国内系统对应用管控这一块进行了大量的魔改,除非你是 QQ 或者微信,否则灭了屏结果都一样。
国内厂商这么做,不是没有原因的,国内应用厂商的全家桶相互唤醒,已经到了一种丧心病狂的地步,牵一发而动全身,一点都不夸张。
在当时我们处理的一些整机卡顿反馈中,抓 Trace 和 Log 来看,都是后台有应用在乱跑,或者后台大量的进程常驻,内存根本不够,而这些普通用户根本就不知道怎么去处理。
下面是当时一些厂商的限制思路,具体策略因 ROM、应用权限和用户设置而异,并不是 Android 对所有后台行为的统一禁令:
- 除非必须,一个应用偷偷拉起来另外一个应用的行为是不被允许的
- 除非必须,一个应用常驻后台是不被允许的
- 除非必须,一个应用在灭屏后在后台乱跑是不被允许的
- 除非必须,一个应用在后台长时间占用 cpu 是不被允许的
- 除非必须,一个应用弹窗是不被允许的
另外手机厂商会有其他的逻辑清理后台的应用,尽管你是合理存在的。
严格的后台管控会影响远程消息的送达,但“未接入厂商 Push SDK 就不能发通知”说得过头了。应用发布本地通知、远程消息到达设备、点击通知后打开界面,是三个不同环节。在具备相应服务和网络条件的设备上,FCM 的后台 notification 消息可以由系统通知栏呈现;厂商推送则有各自的接入与运行条件。
Android 13(API 33)起,普通非豁免通知还受 POST_NOTIFICATIONS 运行时权限约束;通知渠道和用户设置也会影响显示。进程已被回收时,点击通知可能需要冷启动,但等待多长还取决于应用初始化和目标页面,不能一概归因于厂商 SDK。
内存策略
手机厂商会根据内存容量和产品目标,调整缓存进程、内存压力处理及渲染缓存等策略。原文的 LowMemoryKiller 阈值描述带有旧版本背景:Android 9 起,在没有内核 LMK 驱动时使用用户态 lmkd;Android 10 增加基于 PSI 的压力检测,Android 11 又调整了回收压力与 thrashing 的杀进程策略。启用方式仍依赖内核支持和设备配置,见 AOSP lmkd 文档。
在当时排查的一些低内存设备上,我们见过后台反复被杀、重新加载和 CPU 占用升高的问题。不过,内存回收不都等于“把内存写到磁盘”:干净的文件页可以丢弃,需要时再读入;部分匿名页可以压缩到 RAM 中的 zRAM,设备也可能配置额外的 zRAM 写回机制。见 Android 内存分配说明。
Trace 里的 Block I/O 只能作为线索。要结合回收、缺页、实际 I/O 等待和进程重启时间,确认这些工作是否阻塞了当前帧。原文“内存需求只会上升,尽量买 8 GB”的建议已过期;容量、后台保留目标和工作负载需要一起评估。
进程调度策略
渲染依赖的线程如果迟迟拿不到 CPU,可能错过这一帧的截止时间。Trace 中的 Runnable 区间表示线程可运行、正在等待 CPU;这也可能发生在运行后被抢占的阶段,不能仅凭一个长 Runnable 就判定调度器有问题。
常见排查方向包括:
- 同时可运行的线程过多,CPU 已被其他任务占用。
- 线程优先级、CPU 亲和性或 cpuset 限制了它可以使用的资源。
- 调度唤醒、迁移和负载变化没有及时配合,需要结合具体调度事件分析。
CPU 频率、温控限制,以及大核与小核之间的迁移,也可能改变任务完成时间。但“跑到小核”本身不等于卡顿,要看它是否能在截止时间前完成。
WMS/AMS 锁竞争和 Binder 等待要另看依赖链:线程可能在睡眠或等待唤醒,并不一定处于 Runnable。先区分“在 CPU 上执行得慢”“等 CPU”和“等其他线程/资源”,再找原因。调度数据的采集与含义可参考 Perfetto CPU Scheduling。
系统调优往往需要针对上面的情况做对应的处理,给用户一个好的用户体验。具体的调优方式,往往跟系统和 SoC 强相关,又涉及到 Kernel 和功耗,改起来是牵一发而动全身,需要非常谨慎。
渲染线程和主线程
对使用硬件加速 View/HWUI 的应用,主线程和 RenderThread 都是排查对象。RenderThread 随渲染器使用按需建立,不能说每个应用都在进程启动时同时创建这两个线程;游戏自有渲染路径也未必遵循同一结构。Android 5.0 的具体调用路径见RenderThread 流程分析。
Profile GPU Rendering 柱图可以帮助发现某些帧阶段变长,但它不是 GPU、SurfaceFlinger 和屏幕呈现的完整计时。出现异常后,需要继续查看 Trace,常见方向包括:
- 较长时间的 input 事件处理。
- 较长时间的动画或列表更新逻辑,包括 Item 创建和绑定。
- 复杂界面的 Measure、Layout、Draw。
- 大 Bitmap 的频繁上传。
- 复杂渲染指令、GPU 工作或缓冲区等待。
这些方向不代表所有卡顿都发生在应用主线程或 RenderThread 上。系统合成、显示调度和资源竞争同样可能影响最终呈现。
优化的目标是让关键任务按时完成,同时兼顾输入、音频、其他必要任务与功耗。把前台整条渲染链都设成“最高优先级”,不能保证消除资源竞争,也可能损害系统其他功能。
TripleBuffer
Android 4.1 的 Project Butter引入了同步节奏和三缓冲等改进。三缓冲能让生产与消费帧更好地流水执行,但排队也可能增加输入到显示的延迟,它不能保证耗时超标的帧不发生卡顿。
60 Hz 的刷新间隔约为 16.67 ms,90 Hz 约为 11.11 ms,120 Hz 约为 8.33 ms。这些是刷新间隔,不是所有场景都适用的单线程预算。单看 GPU Profile 柱子是否越过 16 ms,既不能完整证明卡顿,也不能用“三缓冲”排除卡顿。
Android 12(API 31)起可以结合 Perfetto FrameTimeline,查看预期与实际时间线、呈现是否延迟,再关联 CPU/GPU 和 SurfaceFlinger 工作。它有版本、采集配置和渲染路径的覆盖边界;没有对应数据时,不能记成“零卡顿”。
虚拟机 - Art 和 Dalvik
ART 改进了代码执行和内存管理,但不会让主线程彻底摆脱 GC 暂停。以 Android 8.0 默认的 Concurrent Copying 收集器为例,大量工作可以并发完成,仍然存在暂停阶段;分配压力、等待线程到达暂停点等因素也会影响耗时。见 AOSP ART GC 调试说明。
所以要同时看分配速率、GC 次数、暂停时间,以及它们是否与慢帧重合。不能把 Dalvik 时期所有卡顿都归到 GC,也不能因为用了 ART 就跳过这部分分析。
温控 && 低电量
温控、低电量省电模式和设备空闲限制是不同机制。它们可能影响 CPU/GPU 频率、后台任务或网络,但具体行为由版本、设备和当前状态决定;不能说一触发温控就必然关核心、杀进程、关特效和断网。
持续游戏后变卡,可能与热限制有关,也可能是场景负载、内存或网络变化。Android 10(API 29)提供 PowerManager 热状态监听,可以与帧耗时一起观察;游戏还可以通过 ADPF 的热管理指导调整帧率和画质,在设备可持续的负载下运行。
所以说选购手机的时候,除了要看 SoC,还要看散热是否做的够好。电池大并不能代替散热设计。
3. 应用层面
复杂的布局
复杂布局可能增加 Measure、Layout、Draw 的工作,拖慢主线程;但层级深浅本身不是结论,要看实际遍历次数、耗时和是否错过帧截止时间。
ListView、RecyclerView 的新的 Item 在初始化的时候也会有类似的问题,由于此时一般是在滑动,这时候的卡顿感会更明显,用户也更容易察觉,这个从 Trace 上也很容易看出来。
过多的业务逻辑
下面保留的是我在 2018 年对淘宝启动体验的吐槽,不代表当前版本:
过多业务逻辑导致的卡顿和响应慢的问题,拿淘宝来举例子最合适不过了,每次你冷启动淘宝的时候,进入主界面马上滑动,总感觉跟吃了屎一样,点按钮点不动,滑界面滑不动,虽然最近的版本有优化,不过你找个低端 Android 机,还是原来的配方。
启动时如果同步加载大量模块、初始化业务或争抢 CPU,首页已经显示也可能难以操作。不过,本文没有附当时的完整 Trace,不能据此确认每次淘宝冷启动都有大量 dex2oat 工作。
AOSP 的 ART 编译说明区分解释执行、JIT 与基于 profile 的 AOT 编译。具体编译行为受安装、已有编译产物、使用记录和系统策略影响;冷启动不等于重新编译整个应用。现代应用还可用 Baseline Profiles优化常用路径,但仍需分别验证首帧和业务可用时间。
内存颠簸
短时间内大量分配临时对象,可能增加 GC 频率和 CPU 开销。Android Studio 内存曲线呈锯齿状,只说明分配与回收在发生,正常应用也会这样;它不能单独证明代码错误或内存泄漏。
要结合分配热点、GC 暂停和帧时间判断是否需要优化。如果一次操作结束、完成回收后,仍保留了不该存在的对象,再继续检查引用关系。
慢网络
慢网络会让内容迟迟不出现,用户也可能把这种等待叫作“卡了”。但它与渲染掉帧不是同一指标:异步请求尚未返回时,界面可以仍然流畅;若主线程被网络、解析或后续更新阻塞,才需要沿线程和渲染路径继续排查。
不合理的设计
复杂设计需要评估性能成本,再决定实现和取舍,设计师的设计往往很炫酷,互相嵌套的动画往往是程序员的噩梦,为了实现这些复杂的效果,程序员往往需要复杂的代码来实现,这对应用的渲染链路的压力是非常大的,而且在不同性能的机器上表现差异很大,高端机用户觉得这个效果棒棒哒,低端机用户卡的要骂娘。
程序员需要有这方面的知识和数据,好与设计师动之以情晓之以理。
不过用户是很挑剔的,现在的用户对性能的要求越来越高,哪怕是低端机用户,所以合适的设计应该考虑到这部分用户、或者针对低端机用户做区分。
代码实现错误
俗称 bug ,很多程序员不喜欢解决性能问题,因为这个东西解决起来,性价比很低,拿我司的程序员来说,解一个性能问题的时间,可以解决十几个界面显示的问题,还未必能真的解决。
不过由于代码实现错误引起的性能问题,必须要最高优先级解决。
4. 流畅度优化闭环
实验室监控 && 模拟用户
开发阶段就用各项数据来做监控和对比,尽量模拟用户的使用环境,尽早暴露性能问题,早日解决。对比时记录设备、系统与应用版本、刷新率、温度和编译状态,区分启动等待、交互响应和渲染掉帧,避免把不同条件下的数据直接比较。
用户流畅度数据收集
在用户使用阶段,收集性能数据,针对这些数据做分析,找出用户最多遇到的性能问题,针对性地做优化。此时也要控制采集频率和开销,收集太多信息会产生观察者效应。
至于采集哪些数据,可以先从与慢帧同时出现的 CPU 等待、内存压力、热状态等指标入手。相关性只是排查线索,不能直接当成因果;仍需回到具体场景和时间线验证。
另外用户的场景判断也非常重要,需要知道用户是在哪个场景出现的卡顿,一旦用户的数量到了一定的级别,这个是很容易发现问题的。
针对性地优化
大数据发现问题后,后续就是针对性地进行优化,把用户最常遇到性能问题的场景进行排序,对最常见的场景进行调研和优化。很多时候需要与应用开发厂商进行沟通,
然后需要把这些场景纳入到实验室监控环境里,做到 实验室监控 —> 模拟用户 — > 大数据收集 —> 针对性优化 —> 实验室监控补充. 这样一个闭环。
关于我 && 博客
下面是个人的介绍和相关的链接,期望与同行的各位多多交流,三人行,则必有我师!
- 博主个人介绍 :里面有个人的微信和微信群链接。
- 本博客内容导航 :个人博客内容的一个导航。
- 个人整理和搜集的优秀博客文章 - Android 性能优化必知必会 :欢迎大家自荐和推荐 (微信私聊即可)
- Android性能优化知识星球:付费社群已于 2026 年停止运营,不再招收新成员;此处保留历史介绍。
一个人可以走的更快 , 一群人可以走的更远
