EN

loading
当 App 有了系统权限,真的可以为所欲为?

2023 年,公开研究披露了某款 Android App 中的漏洞利用代码和动态下发的 DEX。我想看看这些代码尝试调用哪些系统能力,于是有了这篇文章。当时准备仓促,有些代码没有仔细看;下面保留分析过程,并修正能从截图和 AOSP 源码确认的问题。原始文章和代码链接如下:

  1. 深蓝洞察:2022 年度最 “不可赦” 漏洞
  2. XXX apk 内嵌提权代码,及动态下发 dex 分析
  3. Android 反序列化漏洞攻防史话

我不是安全方面的专家。关于漏洞背景,可以参考 Android 反序列化漏洞攻防史话。本文不复现漏洞链,也不把某个接口调用直接等同于已获得 root。

Android 性能优化的术、道、器

黑客与画家

Paul Graham 在其著作 <黑客与画家> 中断言:“不同语言的执行效率差距正变得越来越大,所以性能分析器(profiler)将变得越来越重要。目前,性能分析并没有受到重视。许多人好像仍然相信,程序运行速度提升的关键在于开发出能够生成更快速代码的编译器。代码效率与机器性能的差距正在不断加大,我们将会越来越清楚地看到,应用软件运行速度提升的关键在于有一个好的性能分析器帮助指导程序开发。”
by Paul Graham 黑客与画家

谷歌搜索 「Android 优化工具」,你会找到很多与此相关的内容。他们的问题在于要么是内容高度重复、要么是直接讲使用方法,很少会给你介绍整体性的架构,一不小心就会让人会种「一个工具搞定一切」的错误认知。以笔者团队的多年经验来看,在性能分析领域这种银弹级别的工具是不存在的。工具在发展,老问题会以新的方式变样出现,不掌握核心逻辑的话始终会让你浮于技术的表面。

本文首先系统性的梳理性能分析中的可观测性技术,它涵盖数据类型、抓取方法以及分析方法等三部分内容,之后是介绍谷歌提供的传统「三大件」分析工具。目的是想让你了解数据与测量的基本概念,以及与之对应的在安卓环境中可用的工具,这些可以让你少走一些弯路,直接复用前辈们的经验。

回顾 2021

2021 已经过去,趁着元旦假期,回顾一下 2021,随意一些,想到哪里写哪里吧。主要是对 2021 年的一个回顾,以及 2022 年的展望,2021 年当了爸爸,换了工作(中间还居家无聊了好久),收获了更多的朋友,也算是过的还可以

不过在个人成长方面,甚至感觉有点退步,这让我觉得有点慌,学如逆水行舟,不进则退,2022 年是需要好好深耕的一年,希望能和看到这篇文章的同学一起进步,共勉

另外也盘点了一下知识分享相关的数据,分享了一下这方面的收入,个人新增和推荐的硬件、个人推荐的软件等,感兴趣的可以自取

Android Systrace 响应速度实战 3 :响应速度延伸知识

在讨论 Android 性能问题的时候,卡顿、响应速度、ANR 常被放在一起。它们可能有共同原因,也可能同时出现,但不是按严重程度划分的三个等级。用户说“卡”,还需要分清是动画不连贯、操作后等得太久,还是系统触发了无响应判定。

动画或列表滚动的不连贯通常称为 Jank;应用启动、亮灭屏或场景切换耗时过长属于 响应慢(slow response / high latency);ANR 则由具体的系统超时条件触发。掉帧率、启动耗时和 ANR 率各有测量口径,分析时要分开。

本文是响应速度系列的第三篇,主要是讲在使用 Systrace 分析应用响应速度问题的时候,其中的一些延伸知识,包括启动速度测试、Log 输出解读、Systrace 状态解读、三方启动库等内容

Android Systrace 响应速度实战 2 :响应速度实战分析-以启动速度为例

在讨论 Android 性能问题的时候,卡顿、响应速度、ANR 常被放在一起。它们可能有共同原因,也可能同时出现,但不是按严重程度划分的三个等级。用户说“卡”,还需要分清是动画不连贯、操作后等得太久,还是系统触发了无响应判定。

动画或列表滚动的不连贯通常称为 Jank;应用启动、亮灭屏或场景切换耗时过长属于 响应慢(slow response / high latency);ANR 则由具体的系统超时条件触发。掉帧率、启动耗时和 ANR 率各有测量口径,分析时要分开。

本文是响应速度系列的第二篇,主要是以 Android App 冷启动为例,讲解如何使用 Systrace 来分析 App 冷启动

Android Systrace 响应速度实战 1 :了解响应速度原理

在讨论 Android 性能问题的时候,卡顿、响应速度、ANR 常会一起出现,部分原因也会重叠,但它们不是按严重程度划分的同一个问题。画面节奏异常、操作反馈延迟和具体超时机制触发的 ANR,需要分别确认。用户说“手机卡”或“App 卡”时,可以先把它当作宽泛的体验描述,再问清发生了什么、从哪个动作到哪个结果变慢。

动画播放或列表滑动不连贯,通常称为 Jank;应用启动、亮灭屏或场景切换耗时较长,可描述为 响应慢(slow response / high latency);ANR 则是 Application Not Responding。这些说法帮助组织问题,不是互斥分类;高延迟也可能同时伴随卡顿,ANR 还要按具体触发类型分析。

另外在 App 或者厂商内部,卡顿、响应速度、ANR 这几个性能指标都是有单独的标准的,比如 掉帧率、启动速度、ANR 率等,所以针对这些性能问题的分析和优化能力,对开发者来说就非常重要了

本文是响应速度系列的第一篇,主要讲响应速度相关的理论知识,包括性能工程概述、响应速度涉及到的知识点,以及分析方法。

Android Systrace 流畅性实战 3 :卡顿分析过程中的一些疑问

不同的人对流畅性(卡顿掉帧)有不同的理解,对卡顿阈值也有不同的感知,所以有必要在开始这个系列文章之前,先把涉及到的内容说清楚,防止出现不同的理解,也方便大家带着问题去看这几篇问题,下面是一些基本的说明

  1. 对手机用户来说,卡顿包含了很多场景,比如在 滑动列表的时候掉帧、应用启动白屏过长、点击电源键亮屏慢、界面操作没有反应然后闪退、点击图标没有响应、窗口动画不连贯、滑动不跟手、重启手机进入桌面卡顿 等场景,这些场景跟我们开发人员所理解的卡顿还有点不一样,开发人员会更加细分去分析这些问题,这是开发人员和用户之间的一个认知差异,这一点在处理用户(或者测试人员)的问题反馈的时候尤其需要注意
  2. 对开发人员来说,可以先按 流畅度(画面节奏不连贯)、响应速度(操作后等待过长)和 稳定性(崩溃、ANR 等)整理反馈。这些现象可能重叠;点击没有响应不一定是稳定性故障,需要结合输入、应用状态和日志进一步分类。
  3. 技术上,这三类问题并不是同一个 Message 超时机制的不同阈值。主线程长任务会同时影响输入和绘制,但 GPU、SurfaceFlinger、显示链路、线程调度或远端服务也可能造成延迟。ANR 由具体输入/组件等超时规则触发,崩溃则另有异常或信号等原因;不能仅凭一次长 Message 判定它们。
  4. 流畅性这个系列主要是分析流畅度相关的问题,响应速度和稳定性会有专门的文章介绍,在理解了流畅性相关的内容之后,再去分析响应速度和稳定性问题会事半功倍
  5. 流畅性这个系列主要是讲如何使用 Systrace (Perfetto) 工具去分析,之所以 Systrace 为切入点,是因为影响流畅度的因素很多,有 App 自身的原因、也有系统的原因。而 Systrace(Perfetto) 工具可以从一个整机运行的角度来展示问题发生的过程,方便我们去初步定位问题
Android Systrace 流畅性实战 2 :案例分析 - MIUI 桌面滑动卡顿分析

不同的人对流畅性(卡顿掉帧)有不同的理解,对卡顿阈值也有不同的感知,所以有必要在开始这个系列文章之前,先把涉及到的内容说清楚,防止出现不同的理解,也方便大家带着问题去看这几篇问题,下面是一些基本的说明

  1. 对手机用户来说,卡顿包含了很多场景,比如在 滑动列表的时候掉帧、应用启动白屏过长、点击电源键亮屏慢、界面操作没有反应然后闪退、点击图标没有响应、窗口动画不连贯、滑动不跟手、重启手机进入桌面卡顿 等场景,这些场景跟我们开发人员所理解的卡顿还有点不一样,开发人员会更加细分去分析这些问题,这是开发人员和用户之间的一个认知差异,这一点在处理用户(或者测试人员)的问题反馈的时候尤其需要注意
  2. 对开发人员来说,可以先按 流畅度(画面节奏不连贯)、响应速度(操作后等待过长)和 稳定性(崩溃、ANR 等)整理反馈。这些现象可能重叠;点击没有响应不一定是稳定性故障,需要结合输入、应用状态和日志进一步分类。
  3. 技术上,这三类问题并不是同一个 Message 超时机制的不同阈值。主线程长任务会同时影响输入和绘制,但 GPU、SurfaceFlinger、显示链路、线程调度或远端服务也可能造成延迟。ANR 由具体输入/组件等超时规则触发,崩溃则另有异常或信号等原因;不能仅凭一次长 Message 判定它们。
  4. 流畅性这个系列主要是分析流畅度相关的问题,响应速度和稳定性会有专门的文章介绍,在理解了流畅性相关的内容之后,再去分析响应速度和稳定性问题会事半功倍
  5. 流畅性这个系列主要是讲如何使用 Systrace (Perfetto) 工具去分析,之所以 Systrace 为切入点,是因为影响流畅度的因素很多,有 App 自身的原因、也有系统的原因。而 Systrace(Perfetto) 工具可以从一个整机运行的角度来展示问题发生的过程,方便我们去初步定位问题
Android Systrace 流畅性实战 1 :了解卡顿原理

不同的人对流畅性(卡顿掉帧)有不同的理解,对卡顿阈值也有不同的感知,所以有必要在开始这个系列文章之前,先把涉及到的内容说清楚,防止出现不同的理解,也方便大家带着问题去看这几篇问题,下面是一些基本的说明

  1. 对手机用户来说,卡顿包含了很多场景,比如在 滑动列表的时候掉帧、应用启动白屏过长、点击电源键亮屏慢、界面操作没有反应然后闪退、点击图标没有响应、窗口动画不连贯、滑动不跟手、重启手机进入桌面卡顿 等场景,这些场景跟我们开发人员所理解的卡顿还有点不一样,开发人员会更加细分去分析这些问题,这是开发人员和用户之间的一个认知差异,这一点在处理用户(或者测试人员)的问题反馈的时候尤其需要注意
  2. 对开发人员来说,可以先按 流畅度(画面节奏不连贯)、响应速度(操作后等待过长)和 稳定性(崩溃、ANR 等)整理反馈。这些现象可能重叠;点击没有响应不一定是稳定性故障,需要结合输入、应用状态和日志进一步分类。
  3. 技术上,这三类问题并不是同一个 Message 超时机制的不同阈值。主线程长任务会同时影响输入和绘制,但 GPU、SurfaceFlinger、显示链路、线程调度或远端服务也可能造成延迟。ANR 由具体输入/组件等超时规则触发,崩溃则另有异常或信号等原因;不能仅凭一次长 Message 判定它们。
  4. 流畅性这个系列主要是分析流畅度相关的问题,响应速度和稳定性会有专门的文章介绍,在理解了流畅性相关的内容之后,再去分析响应速度和稳定性问题会事半功倍
  5. 流畅性这个系列主要是讲如何使用 Systrace (Perfetto) 工具去分析,之所以 Systrace 为切入点,是因为影响流畅度的因素很多,有 App 自身的原因、也有系统的原因。而 Systrace(Perfetto) 工具可以从一个整机运行的角度来展示问题发生的过程,方便我们去初步定位问题
Android App 链式唤醒分析

MIUI 12 的发布, 将之前一直是应用开发者和 Rom 开发者斗争最激烈的部分展示给了普通消费者, 让普通消费者也知道了这场斗争的细节, 正所谓 “魔高一尺道高一丈”, Rom 开发者由于有更高的代码修改权限, 始终占据着上风 ; App 开发者当然也不甘示弱, 各种保活拉起黑科技层出不穷,甚至 Google 都参与到了这部分斗争中, 居中调和, 制定各种规则来规范双方. 当然斗争对双方来说都算是好事, 毕竟任何一方完全的胜利都会导致 “狡兔死走狗烹,飞鸟尽良弓藏”

不过双方斗争的受害者无疑还是使用手机的消费者, App 如果斗争成功, 那么手机上各种后台进程乱跑, 杀不掉, 占用 CPU 和内存, 这不是消费者想看到的 ; 如果 Rom 开发者斗争成功, App 的体验必定会大打折扣, 各位 App 开发者应该深有体会.

从文章最后一段可以看到, 其实各个手机厂商对付这一套都有自己的策略, 基本上都可以搞定自启动和关联启动. 至于隐私, 李彦宏曾经说过 “中国人对隐私问题的态度更加开放,也相对来说没那么敏感。如果他们可以用隐私换取便利、安全或者效率。在很多情况下,他们就愿意这么做“ . 大家想想在微信里面复制一段话打开到淘宝就可以自动跳转到这个物品, 方不方便? 好不好用? 还想不想用? 剪贴板再借我看一看?

Android Systrace 基础知识 - SurfaceFlinger 解读

本文是 Systrace 系列文章的第五篇,主要是对 SurfaceFlinger 的工作流程进行简单介绍,介绍了 SurfaceFlinger 中几个比较重要的线程,包括 Vsync 信号的解读、应用的 Buffer 展示、卡顿判定等,由于 Vsync 这一块在 Systrace 基础知识 - Vsync 解读 和 Android 基于 Choreographer 的渲染机制详解 这两篇文章里面已经介绍过,这里就不再做详细的讲解了。

本系列的目的是通过 Systrace 这个工具,从另外一个角度来看待 Android 系统整体的运行,同时也从另外一个角度来对 Framework 进行学习。也许你看了很多讲 Framework 的文章,但是总是记不住代码,或者不清楚其运行的流程,也许从 Systrace 这个图形化的角度,你可以理解的更深入一些。

Android Systrace 基础知识 - CPU Info 解读

本文是 Systrace 系列文章的第十二篇,主要是对 Systrace 中的 CPU 信息区域(Kernel)进行简单介绍,简单介绍了如何在 Systrace 中查看 Kernel 模块输出的 CPU 相关的信息,了解 CPU 频率、调度、锁频、锁核相关的信息

本系列的目的是通过 Systrace 这个工具,从另外一个角度来看待 Android 系统整体的运行,同时也从另外一个角度来对 Framework 进行学习。也许你看了很多讲 Framework 的文章,但是总是记不住代码,或者不清楚其运行的流程,也许从 Systrace 这个图形化的角度,你可以理解的更深入一些。

Android Systrace 基础知识 - Triple Buffer 解读

本文是 Systrace 系列文章的第十一篇,主要是对 Systrace 中的 Triple Buffer 进行简单介绍,简单介绍了如何在 Systrace 中判断卡顿情况的发生,进行初步的定位和分析,以及介绍 Triple Buffer 的引入对性能的影响

本系列的目的是通过 Systrace 这个工具,从另外一个角度来看待 Android 系统整体的运行,同时也从另外一个角度来对 Framework 进行学习。也许你看了很多讲 Framework 的文章,但是总是记不住代码,或者不清楚其运行的流程,也许从 Systrace 这个图形化的角度,你可以理解的更深入一些。

Android Systrace 基础知识 - Binder 和锁竞争解读

本文是 Systrace 系列文章的第十篇,主要是对 Systrace 中的 Binder 和锁信息进行简单介绍,简单介绍了 Binder 的情况,介绍了 Systrace 中 Binder 通信的表现形式,以及 Binder 信息查看,SystemServer 锁竞争分析等

本系列的目的是通过 Systrace 这个工具,从另外一个角度来看待 Android 系统整体的运行,同时也从另外一个角度来对 Framework 进行学习。也许你看了很多讲 Framework 的文章,但是总是记不住代码,或者不清楚其运行的流程,也许从 Systrace 这个图形化的角度,你可以理解的更深入一些。

Android Systrace 基础知识 - Vsync 解读

本文是 Systrace 系列文章的第七篇,主要是是介绍 Android 中的 Vsync 机制。文章会从 Systrace 的角度来看 Android 系统如何基于 Vsync 每一帧的展示。Vsync 是 Systrace 中一个非常关键的机制,虽然我们在操作手机的时候看不见,摸不着,但是在 Systrace 中我们可以看到,Android 系统在 Vsync 信号的指引下,有条不紊地进行者每一帧的渲染、合成操作,使我们可以享受稳定帧率的画面。

本系列的目的是通过 Systrace 这个工具,从另外一个角度来看待 Android 系统整体的运行,同时也从另外一个角度来对 Framework 进行学习。也许你看了很多讲 Framework 的文章,但是总是记不住代码,或者不清楚其运行的流程,也许从 Systrace 这个图形化的角度,你可以理解的更深入一些

Android App 启动优化全记录

本文参考了目前大部分 Android 应用启动优化的方案,将大家的方案做一个汇总,如果你有这方面的需求,只需要对照这篇文章,看看其他人的方案,查漏补缺。很多方案是要根据具体的业务去做优化的,所以这里也没有对每一种方案进行详细的介绍,要用到哪一个方案的时候,可以具体去网上查找对应方案的具体实现方法,这里只是做一个汇总

另外我还加上了部分系统厂商所做的启动相关的优化,不过只写了一些我知道的,还有一些厂商有黑科技,就不在这里的讨论范围了。知道厂商做的事情,可能也会帮助到你,比如联系厂商做白名单、接入厂商 SDK 等

Android Systrace 基础知识 - MainThread 和 RenderThread 解读

本文是 Systrace 系列文章的第九篇,主要是是介绍 Android App 中的 MainThread 和 RenderThread,也就是大家熟悉的主线程和渲染线程。文章会从 Systrace 的角度来看 MainThread 和 RenderThread 的工作流程,以及涉及到的相关知识:卡顿、软件渲染、掉帧计算等

本系列的目的是通过 Systrace 这个工具,从另外一个角度来看待 Android 系统整体的运行,同时也从另外一个角度来对 Framework 进行学习。也许你看了很多讲 Framework 的文章,但是总是记不住代码,或者不清楚其运行的流程,也许从 Systrace 这个图形化的角度,你可以理解的更深入一些

Android Systrace 基础知识 - Input 解读

本文是 Systrace 系列文章的第六篇,主要是对 Systrace 中的 Input 进行简单介绍,介绍其 Input 的流程; Systrace 中 Input 信息的体现 ,以及如何结合 Input 信息,分析与 Input 相关的问题

本系列的目的是通过 Systrace 这个工具,从另外一个角度来看待 Android 系统整体的运行,同时也从另外一个角度来对 Framework 进行学习。也许你看了很多讲 Framework 的文章,但是总是记不住代码,或者不清楚其运行的流程,也许从 Systrace 这个图形化的角度,你可以理解的更深入一些。

Android 中的“后台无效动画“行为分析

这篇文章记录的是 2019 年遇到的后台动画问题:应用界面不可见了,进程里却仍有动画工作在执行。但是当用户知道一个 App 退到后台之后还在持续做无效的动画,而这个动画完全是无意义的,而且用户还不知道他在做动画,消耗用户那可怜的电量的时候,轻则被多任务杀掉,禁止后台运行,重则直接卸载。

这个问题容易被忽略。当时我使用 Systrace ,在多开应用后退回桌面,左右滑动并抓取 Systrace ,发现部分已离开的应用仍在频繁执行动画回调。复查时应固定操作和应用版本,并记录界面可见性,不能把“打开很多应用”当成必要或充分条件。

这里讨论的是界面已不可见、业务也不再需要,却仍持续推进的动画。它会增加不必要的工作;但进程还活着不等于能无限制使用 CPU,现代系统还可能冻结 cached 进程。往 Choreographer 提交动画回调的入口很多,最终要结合具体调用栈、播放状态和库版本定位,不能仅凭一个 animation slice 判定原因

Android 基于 Choreographer 的渲染机制详解

本文介绍了 App 开发者不经常接触到但是在 Android Framework 渲染链路中非常重要的一个类 Choreographer。包括 Choreographer 的引入背景、Choreographer 的简介、部分源码解析、Choreographer 与 MessageQueue、Choreographer 和 APM,以及手机厂商基于 Choreographer 的一些优化思路

Choreographer 让动画、部分输入处理和 View 更新围绕显示时序协调执行。它在有待处理工作时请求帧回调,而不是每个物理刷新周期都无条件唤醒 App。2019 年常见的 60Hz 屏幕刷新间隔约为 16.67ms;90Hz、120Hz 分别约为 11.11ms、8.33ms,现代设备还可能动态切换刷新率。回调及时不等于画面已经呈现,后续还涉及 RenderThread、GPU 和合成显示链路。了解这套流程,也有助于理解 Message、Handler、Looper、MessageQueue、Measure、Layout 和 Draw。

Android 中的卡顿丢帧原因概述 - 低内存篇

在Android 中的卡顿丢帧原因概述 - 系统篇 这篇文章中, 实际案例这里我们有列举一些由于系统低内存导致的卡顿, 由于 Android 低内存对整机性能影响比较大, 所以单独写一篇文章, 来概述系统低内存对整机性能的影响 .

随着 Android 系统版本的更迭, 以及 App 的代码膨胀, Android 系统对内存的需求越来越大, 在写作当年的 2019 年,市面上还存在着大量 4GB 内存及以下的机器, 这部分用户就很容易遇到整机低内存的情况, 尤其是在系统大版本更新、同时运行的应用和服务增多的情况下 .

Android 内存压力可能导致性能问题, 具体表现就是响应慢和卡顿 . 比如启动一个应用要花比平时更长的时间 ; 滑动列表会掉更多帧 ; 后台的进程减少导致冷启动变多 ; 额外回收和重启工作也可能增加功耗,但发热本身不能证明低内存, 下面我会概述发生这些性能问题的原因 . Debug 的方法, 以及可能的优化措施 .

Android 桌面被杀问题分析案例

写这篇文章的契机是因为一个实际遇到的问题, 这个问题其实不难, 不过在分析了这个问题然后写日记的时候, 我突然觉得这个问题分析的过程有必要记录一下, 分享给大家 . 分析过程中有用到一些工具, 一些方法, 也从另外一个聪明的小伙伴梅明那里学到了一些分析技巧和工具的使用技巧 .

这篇文章中分析过程包括我之前在Android 中的卡顿丢帧原因概述 - 方法论 里面提到的一些工具, 包括 : 复现视频 \ Event Log \ Android Studio 源码和 App Debug \ Android Studio Profile \ Systrace \ Dumpsys \ PS 等 . 大多数工具大家都在开发过程中使用过, 这次分析正是使用了这些工具相互配合, 最终找到的问题的原因.

大家看下来可能会觉得, 这么简单一个问题还需要写一篇文章 ? 我写这篇文章的目的一是为了记录给自己, 二是觉得分析过程比较有普遍性, 包括分析思路和工具的使用, 如果可以帮助到大家, 那么最好不过了, 如果你也有好的思路或者独家调试技巧, 欢迎大家扫描关于我 里面的讨论群二维码加入群聊, 共同进步!

Android 中的卡顿丢帧原因概述 - 系统篇

技术复核 · 2026-10-13。 本文案例与截图来自 2019 年。此次按 Android 8.1/9/16 的相关源码、Linux v6.6 文档及现行 Android 文档核查,保留原始图片和作者经验;修正将长 slice、核号、内存回收或输入节奏直接等同根因的结论。没有重新运行原设备或回放完整 Trace,缺少的现场条件不作补造。

在应用篇中,我们列举了应用侧的卡顿问题。这一篇沿系统服务、显示、调度和内存路径整理案例。各设备的硬件、内核与厂商实现不同,定位时应保留系统版本和具体配置。

手机厂商和 App 开发者通常会通过优化组、Matrix 或自有监控方案收集线索。系统权限有助于获取更多数据,但采集范围仍受构建类型、内核配置和数据源开关影响。

流畅度不能仅等同于平均 FPS。60 Hz 下的一秒平均 55 FPS,无法说明延迟集中在哪几帧,也不能直接代表所有人的感知;应检查目标节奏、实际呈现间隔和输入响应。静止界面不需要每个刷新周期提交新内容。本系列四篇如下:

Android 中的 Activity Launch Mode 详解

技术复核 · 2026-10-13。 本文保留 2019 年四种启动模式的操作记录,按 AOSP android-9.0.0_r1、android-16.0.0_r1 核对任务选择、affinity 与最近任务行为,并补充 Android 12(API 31)的 singleInstancePerTask。旧记录未注明设备完整版本,本次没有真机重跑,不能当作当前系统的逐步实测。

Android 中的 Activity 有几种重要的启动模式:standard、singleTop、singleTask、singleInstance。网上讲这些模式的文章不少,我这里写了个 Demo,想从任务中的 Activity 排列给大家看它们的区别;较新的 singleInstancePerTask 放在后面补充。

普通任务内导航通常后进先出。下方 A -> B 表示操作顺序;“栈内容”按顶部在前列出实际排列。留意每一步之后的变化,边操作边对照会好理解一些。重复发起启动不一定增加实例。Task 是系统管理的任务,不等于进程,也不等于最近任务列表中的一张卡片。

Demo 我也放到了 GitHub:AndroidLunchModeTest。本次核对的快照为 eaa1f987e332e0f85187a911ad9ae01cd20fff05。工程 compile/target SDK 29、min SDK 26;源码包名为 com.example.lunchmodetest,与下方保留的旧日志 com.example.launchmodetest 不同。

运行前需要按每个案例核对所有跳转目标:快照中 MainActivity.startSingleTopActivity 实际跳到 SingleTaskActivity,StandardActivity 默认跳到 SingleInstanceWithAffinityActivity,仅改一个目标无法自动跑完全部案例。类名 WithAffinity 表示旧命名,实际 manifest 配置为空 affinity;SingleTopWithAffinityActivity 甚至未声明 singleTop,不能凭类名判断模式。本次只核查代码,没有改动或编译这个示例工程。

下面先按同一用户、普通前台 Activity 发起、无额外 Intent flags 的条件解释。若把旧工程升级到 target SDK 31+,还需为带 intent-filter 的组件显式配置 android:exported,其中 Launcher 入口设为 true。

Android Systrace 基础知识 -- 分析 Systrace 预备知识

2026-10-13 技术更新:本文保留 2019 年起积累的旧 Systrace 截图,其中也有后补的案例。颜色与快捷键属于 legacy UI;Linux 状态说明参照 v6.6 文档,现代入口核对到 Perfetto UI v58.3(11fbaed83)。原图里的 Self Time、唤醒及调度状态注释有几处不准确,已在相邻正文说明;截图不等于本次设备实测。

本文是 Systrace 系列文章的第二篇,主要是讲解一些分析 Systrace 的预备知识, 有了这些预备知识, 分析 Systrace 才会事半功倍, 更快也更有效率地找到问题点.

本文介绍了如何查看 Systrace 中的线程状态, 如何对线程的唤醒信息进行分析, 如何解读信息区的数据, 以及介绍了常用的快捷键. 通过本篇文章的学习, 相信你可以掌握进程和线程相关的一些信息, 也知道如何查看复杂的 Systrace 中包含的关键信息

Android Systrace 基础知识 - SystemServer 解读

2026-10-13 技术更新:保留原有历史截图和代码。文中代码片段已对照 AOSP android-10.0.0_r1,现代差异以 android-16.0.0_r1 为例;这不表示原截图运行的就是这些版本,原始 Trace、ROM 和构建信息并未附上。窗口动画归属、StartingWindow 与线程相互影响的旧说法已在下文修正。

本文是 Systrace 系列文章的第四篇,主要是对 SystemServer 进行简单介绍,介绍了 SystemServer 中几个比较重要的线程,由于 Input 和 Binder 比较重要,所以单独拿出来讲,在这里就没有再涉及到。

本系列的目的是通过 Systrace 这个工具,从另外一个角度来看待 Android 系统整体的运行,同时也从另外一个角度来对 Framework 进行学习。也许你看了很多讲 Framework 的文章,但是总是记不住代码,或者不清楚其运行的流程,也许从 Systrace 这个图形化的角度,你可以理解的更深入一些。

Android Systrace 基础知识 -- Why 60 fps ?

2026-10-13 技术更新:本文原发表于 2019 年,以 60 Hz 设备解释帧节奏。60 FPS 不是所有 Android 设备的固定标准;旧文中的统一 16.67 ms 预算、帧率不匹配及功耗结论已在下文修正,并补充 Android 11 / API 30、Android 12 / API 31 起的适配与分析入口。

本文是 Systrace 系列文章的第三篇,解释一下为何大家总是强调 60 fps。这里的 FPS 指应用画面的帧率,Hz 指屏幕刷新率,两者统计的对象不同,可以参考这篇文章:新的流畅体验,90Hz 漫谈

本系列的目的是通过 Systrace 这个工具,从另外一个角度来看待 Android 的运行,从另外一个角度来对 Framework 进行学习。也许你看了很多讲 Framework 的文章,但是总是记不住代码,或者不清楚其运行的流程,也许从 Systrace 这个图形化的角度,你可以理解的更深入一些。

本文先分清帧率与刷新率,再讨论帧节奏、功耗和响应延迟。到了 90 Hz、120 Hz 设备上,仍需要让内容更新与显示时序配合,但不再把 60 FPS 或 16.67 ms 当成统一标准。

Android Systrace -- 系列文章目录

2026-10-13 技术更新:本页原标注日期为 2019 年,保留了更早教程的更新记录。旧 Systrace 工具流程已过时;历史截图、源码和实验按各篇注明的 Android 版本阅读,不能直接当作当前系统实现。新抓取与分析流程从下方 Perfetto 系列开始。

随着 Systrace 的功能越来越完善,加上 Android 版本的更迭,之前写的 Systrace 系列教程已经有点过时;另外随着自己技能的完善,从 Systrace 里挖掘了更多的信息,对解决各种性能问题很有帮助。这些技能我需要记录下来,增强自己的总结和归纳的能力,如果能帮助到看文章的人,也是极好的

本系列的目的是通过 Systrace 这个工具,从另外一个角度来看待 Android 系统整体的运行,同时也从另外一个角度来对 Framework 进行学习。也许你看了很多讲 Framework 的文章,但是总是记不住代码,或者不清楚其运行的流程,也许从 Systrace 这个图形化的角度,你可以理解的更深入一些。

Android 新的流畅体验,90Hz 漫谈
版本说明(2026-10-13 核查):本文写于 2019 年,机型评价、“90 Hz 是当时较好选择”和购机展望保留为历史看法,不是当前购买建议。下文修正刷新率、帧率和输入处理的解释,补充 Android 11/API 30 与 Android 15 QPR1 等版本的变化。原 Trace 裁图没有完整采集条件,不作为新设备实测。 PC 上高刷新率屏幕很早就出来了,但是 Android 上高刷新率屏幕出现在 Android 手机上还只是这两年的事情,尽管雷蛇在 2017 年就推出了 120Hz 屏幕的手机,但是反响平平;而个人认为今年努比亚的红魔 3 和 OnePlus ...
Android 系统开发源码环境搭建
不管是 Android App 开发工程师还是 Android 系统开发工程师,对 Android 系统有一定的了解是很有必要的,正好我这几天在家里搭建了个开发环境,把过程分享出来,有需要的人可以看一下。 大概的步骤包含下面几个: 安装 Ubuntu 系统 配置 Ubuntu 系统 安装必备的软件 配置网络访问环境 (可选) 下载 AOSP 代码 配置编译环境并编译 Pixel 的代码 刷机 修改和编译 Framework 、Service、Res 版本说明(2026-10-13 核查):原文是 2018 年的环境记录。截图可见 Ubuntu 18.04.1、PLATFORM_VE...
Android 系统不释放内存吗?
除了 CPU,很多用户在选购手机的时候通常也会考虑内存大小,不同版本内存的手机价格也不一样,买多大内存的合适呢?Android 系统是怎么管理内存的呢?普通用户对 Android 手机的内存使用总是一头雾水,这个应用到底占了多少内存?系统到底占了多少内存?内存对我手机的使用体验有什么影响?到底怎么才能用好 Android 手机?换新手机换多大内存的会比较合适呢? 知乎上有一个问题,一个用户问 “Android 系统不释放内存吗?”,用户并不是不知道系统会释放内存,而是想知道其中的细节,好优化使用的体验,下面我就从用户的几个问题入手,来简单说明一下,比较深入的细节我后续的文章会详细介绍。 ...
关于 Android 系统流畅性的一些思考
版本说明(2026-10-13 核查):本文写于 2018 年。文中的机型、应用体验和厂商评价保留为当时的个人观察,旧硬件排名与购机建议已过期。下文修正技术错误,并补充 Android 10/12/13 等版本的变化;没有把历史体验当成当前版本的实测。 最近一直想写一些关于 Android 系统流畅度的东西,因为流畅度这个东西,是消费者最直接能体验到的,再加上 Android 一直为人诟病的越用越卡顿,使得大家在提到安卓机的时候,都会有一丝阴影。这也是大部分人买手机首先会考虑 iPhone 的一个原因。 由于 Google 对 Android 持开放态度,各个手机...
知乎 救救你的 StartingWindow

我们经常说 iOS 整机体验要比 Android 好,这里有第三方软件的功劳(iOS 版本质量要高于 Android 版本质量),当然也归功于苹果对 iOS 的封闭系统的管控。应用想上 App Store,就得先过审核,不合规就给你打回来。

今天我们要说的是系统在应用内容就绪前提供的启动过渡画面。Android 常称之为 StartingWindow,iOS 的对应概念是 Launch Screen;两者不能等同于应用启动后自己展示的广告 Activity 或业务首页。

我原先把 iOS 启动画面说成“必须是一张图片”,这里说错了:Xcode 6 发布说明明确记录 iOS 8 起支持 XIB/Storyboard 启动画面。它们帮助系统尽早给出反馈,但“点击后零延迟”不是可保证的时序。Android 的旧实现允许通过主题影响启动预览,也有禁用预览或透明窗口的路径;具体规则要看系统版本。

2017 年度好物推荐 - 给辛勤工作的自己一点奖励

2017 不知不觉已经走过,博客已经许久没有更新了,一个原因是越来越觉得自己的学识浅薄,怕写了技术误了大家,另一个原因是自己太懒了。鉴于上面两个原因,我决定此博客的更新,不再非要更新技术文章,一些我觉得有意义的事情、思考等,也会更新上来。一方面自己做个记录,如果能顺带给读者带来一点帮助,那自然是最好的(虽然没几个读者…)

2017 既然才刚刚过去,我觉得有必要把 2017 年里面我觉得体验很棒或者对工作生活很有帮助的东西推荐给大家,或许 2018 你会需要他们。推荐的内容包含了 App、硬件、书籍、器材等,需要说明的是,这些东西是我觉得 2017 年给我带来很大帮助的,适合我不一定适合你。话不多说,直接上内容吧!

Android 中如何计算 App 的启动时间?

之前有人在知乎提问:“怎么计算apk的启动时间?” :

利用python或者直接用adb命令怎么计算apk的启动时间呢?就是计算从点击图标到apk完全启动所花费的时间。比如,对游戏来说就是点击游戏图标到进入到登录界面的这段时间。
已知的两种方法貌似可以获取,但是感觉结果不准确:一种是,adb shell am start -w packagename/activity,这个可以得到两个值,ThisTime和TotalTime,不知道两个有什么区别,而且与实际启动时间不匹配,两者相加都可能比实际启动时间小(测试游戏的时候差别更大);另外一种是通过adb logcat的方式,感觉获取的结果也与实际有差别。

我和另外一个同事郭启发 针对两个方面进行了回答,不过毕竟知乎上看的人会比较少,所以我在征得他的同意之后,将这两个答案整理了一下,记录到博客中,一来算是一个小的总结,之后自己看得时候比较方便,二来给需要的同学一个更加方便的途径。

Android 应用启动优化:一种 DelayLoad 的实现和原理(下篇)

上一篇文章我们使用第三种方法来实现延迟加载。不过上一篇写的比较简单,只是讲解了如何去实现,这一篇就来讲一下为何要这么做,以及这么做后面的原理。
其中会涉及到一些 Android 中的比较重要的类,以及 Activity 生命周期中比较重要的几个函数。
其实这个其中的原理比较简单,不过要弄清楚其实现的过程,还是一件蛮好玩的事情,其中会用到一些工具,自己加调试代码等,一步一步下来,自己对 Activity 的启动的理解又深了一层,希望大家读完之后也会对大家有一定的帮助。

Android 应用启动优化 - 一种 DelayLoad 的实现和原理(上篇)

在 Android 开发中,应用启动速度是一个非常重要的点,应用启动优化也是一个非常重要的过程.对于应用启动优化,核心思想就是在启动过程中少做事情,具体实践的时候无非就是下面几种:

  1. 异步加载
  2. 延时加载
  3. 懒加载

不用一一去解释,做过启动优化的估计都使用过,本篇文章将详细讲解一下一种延时加载的实现以及其原理.
这种加载的实现很简单,但是其中的原理可能比较复杂,还涉及到Looper/Handler/MessageQueue/VSYNC等.以及其中碰到的一些问题,还会有一些我自己额外的思考.

Android hwui 中 RenderThread 工作流程

前言

本篇文章是自己的一个学习笔记,记录了 Android 5.0 中 hwui 中的 RenderThread 的简单工作流程。由于是学习笔记,所以其中一些细节不会太详细,我只是将大概的流程走一遍,将其工作流标注出来,下次遇到问题的时候就可以知道去哪里查。

下图是我用 Systrace 抓取的应用启动时 RenderThread 第一次 Draw 的历史 Trace。它能帮助观察线程内的执行顺序,但 DrawFrame 区间结束不等于画面已显示:还需要核对 GPU 完成、缓冲区消费、合成和显示的时点。启动期间可能先看到 StartingWindow,它的退出也不能仅凭这段 CPU Trace 判断。

Android 代码内存优化建议 - OnTrimMemory 优化

Android 内存优化系列文章:

  1. Android代码内存优化建议-Android官方篇
  2. Android代码内存优化建议-Java官方篇
  3. Android代码内存优化建议-Android资源篇
  4. Android代码内存优化建议-OnTrimMemory优化

onTrimMemory(int level) 从 Android 4.0(API 14)提供,用于提示应用在合适的时机减少不必要的内存占用。合理缩减缓存有助于系统保留更多后台进程,但不能保证应用不被终止,也不能保证下次返回一定更快。

本文仍用问答方式介绍回调的作用、接入和资源清理。重点是按资源的用途决定保留什么、释放什么,并确保返回界面时能够恢复。

Android 代码内存优化建议 - Android 资源篇

Android 内存优化系列文章:

  1. Android代码内存优化建议-Android官方篇
  2. Android代码内存优化建议-Java官方篇
  3. Android代码内存优化建议-Android资源篇
  4. Android代码内存优化建议-OnTrimMemory优化

我写这篇文章的初衷,是希望在动手写代码前,先把容易出内存问题的地方弄清楚,少留些问题到后面排查。下面从 Bitmap、数据库查询、列表复用和绘制等方面展开,看看资源由谁创建、谁持有、什么时候不再需要。这里有资源滞留、重复分配,也有泄漏,几种情况要分开处理。

Android 代码内存优化建议 - Android 官方篇

Android 内存优化系列文章:

  1. Android代码内存优化建议-Android官方篇
  2. Android代码内存优化建议-Java官方篇
  3. Android代码内存优化建议-Android资源篇
  4. Android代码内存优化建议-OnTrimMemory优化

为了让垃圾回收器释放不再使用的对象,需要避免让长生命周期的对象继续持有已经无用的引用。判断条件是对象是否还能从 GC Roots 到达,并不是“有没有其他对象引用它”:一组互相引用、但整体不可达的对象也可以被回收。失去可达性不代表立即执行 GC,更不代表这部分内存立即归还给系统。

内存管理还包括缓存上限、资源所有权和组件生命周期。文件、连接和 native 资源应按各自接口及时关闭或释放,不能只等 Java 对象被 GC。

Nexus6 with Android M 开启多窗口模式

2015 年 5 月 28 日,Google 在 I/O 发布了 Android M Developer Preview,支持 Nexus 6 等设备。这篇记录的是当时的体验,下面是桌面和彩蛋界面。

已过期的实验流程 · 技术复核(2026-10-13):修改系统属性打开隐藏多窗口开关,仅作为 Nexus 6(shamu)与 2015 年 Android M 预览版的历史记录。Google 后续公告把首轮预览版标为 MPZ44Q;本文没有保留设备构建号输出,不能把它当成本机镜像的核验结果。今日的正式多窗口适配见文末版本说明,不需要这套改系统流程。

Android 小技巧 - 5

本文是一篇译文,这篇是这个系列的第五篇.讲述的是Android开发中遇到的一些好用的小技巧,或者一些实用的API,很多人都知道,但也有人不知道,记录下来,如果能帮助到大家,也是极好的.由于不是严格的博文,所以翻译也不那么严格,有些工具和类我也会经常用,所以我会根据自己的想法去写.有些地方作者并没有将这个工具的作用讲出来,我会补充上去.

技术复核(2026-10-13):原文发表于 2014 年,本译文发表于 2015 年。旧 Support Library 链接改为 AndroidX;外部存储、缩略图和应用语言补充新版本用法。清除应用数据和数据库让出事务的副作用也在对应条目中明确说明。

Android 小技巧 - 1

2026-10-13 核查:这份清单原写于 2014 年,主要面向 Android View 系统。多数 API 仍然有效;旧版 Html.fromHtml(String) 从 API 24 废弃,下面补充替代签名,并修正缓存目录、布局加载和动画反向播放的说明。

本文是一篇译文,这篇是这个系列的第一篇.讲述的是Android开发中遇到的一些好用的小技巧,或者一些实用的API,很多人都知道,但也有人不知道,记录下来,如果能帮助到大家,也是极好的.由于不是严格的博文,所以翻译也不那么严格,有些工具和类我也会经常用,所以我会根据自己的想法去写.有些地方作者并没有将这个工具的作用讲出来,我会补充上去.