【AOSP】Android Dump 开发与调试指南

在 Android 系统开发与调试中,dump 是一个不可或缺的强大工具。它能够提供关于系统服务、应用程序状态以及底层硬件信息的详细快照。对于希望深入了解 Android 系统内部工作原理、排查复杂问题或进行性能优化的开发者来说,掌握 dump 的使用至关重要。

在这里插入图片描述

一、什么是 Android Dump?

Android Dump 是一种通过 dumpsys 工具获取系统服务和应用程序状态信息的调试技术。这些信息涵盖了广泛的领域,从电池状态、内存使用、网络连接,到窗口管理、活动堆栈等等。开发者可以通过 Android 调试桥 (adb) 从命令行调用 dumpsys,从而获取到连接设备上运行的各种系统服务的诊断输出。

例如,当你遇到应用无响应 (ANR) 问题时,系统会自动进行 dump 操作,生成包含当前所有线程堆栈信息的 traces.txt 文件,这对于分析卡死原因至关重要。

二、Android Dump 的工作原理

Android 的 dump 机制核心依赖于 Binder IPC (跨进程通信) 框架。Android 的系统服务各自运行在独立的进程中,并通过 ServiceManager 进行注册和管理。dumpsys 工具本身是一个运行在设备上的可执行文件,它并不直接了解各个服务的内部状态。当用户执行 adb shell dumpsys <service_name> 命令时,其实质上是启动了 dumpsys 这个客户端程序,其工作流程如下:

  1. 获取 ServiceManager 代理dumpsys 进程首先会获取到 ServiceManager 的一个代理对象。
  2. 查询服务:通过这个代理对象,dumpsys 向 ServiceManager 查询指定服务(例如 activitywindow 等)的 Binder 代理对象。
  3. 发起 Binder 调用dumpsys 通过获取到的服务代理对象,调用一个名为 dump 的方法,并将需要传递的参数(如果有的话)一并发送。
  4. 服务端执行 dump:服务进程接收到这个 Binder 调用后,会在其自身的 dump 方法中实现具体的逻辑,将当前服务的内部状态信息输出到一个文件描述符(FileDescriptor)中。
  5. 数据回传与显示:输出的数据通过 Binder 机制回传给 dumpsys 进程,并最终显示在你的命令行终端上。

简而言之,dumpsys 充当了一个“信使”的角色,它通过 Binder 这座桥梁,请求并获取了远端系统服务的内部状态信息。

为了更深入地理解 dump 的工作原理,我们来探究一下相关的源代码。

2.1 dumpsys 命令的源码实现

dumpsys 命令的源码位于 AOSP (Android Open Source Project) 的 frameworks/native/cmds/dumpsys/ 目录下。核心逻辑在 dumpsys.cppmain.cpp 文件中。

  • main.cpp: 这是 dumpsys 可执行文件的入口。它的主要作用是解析命令行参数,并调用 Dumpsys 类的 main 方法。

  • dumpsys.cpp: 这个文件包含了 dumpsys 的核心实现。在 Dumpsys::main 方法中,它会连接到 ServiceManager,并根据用户传入的服务名称,获取到对应服务的 IBinder 接口。

    // frameworks/native/cmds/dumpsys/dumpsys.cppsp<IServiceManager> sm = defaultServiceManager();
    ...
    if (sm != nullptr) {Vector<String16> services = sm->listServices();...sp<IBinder> service = sm->checkService(String16(serviceName));if (service != nullptr) {int err = service->dump(STDOUT_FILENO, args);...}
    }
    

    上述代码片段展示了 dumpsys 如何通过 defaultServiceManager() 获取 ServiceManager 的实例,然后通过 checkService 获取到目标服务的 IBinder 代理对象。最后,调用该对象的 dump 方法,并将标准输出的文件描述符 STDOUT_FILENO 和其他参数 args 传递过去。

2.2 系统服务的 dump 方法实现

每个提供 dump 功能的系统服务,都会在其代码中实现 IBinder 接口的 dump 方法。我们以 ActivityManagerService (AMS) 为例,它的服务名称是 activity。其源码位于 frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.javapublic final class ActivityManagerService extends IActivityManager.Stubimplements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {// ...@Overrideprotected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)!= PackageManager.PERMISSION_GRANTED) {pw.println("Permission Denial: can't dump ActivityManager from from pid="+ Binder.getCallingPid()+ ", uid=" + Binder.getCallingUid());return;}// ... a lot of logic to handle different arguments in 'args' ...if (args.length > 0) {String cmd = args[0];if ("activities".equals(cmd) || "a".equals(cmd)) {// dump activities stack} else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {// dump broadcast state} else if ("services".equals(cmd) || "s".equals(cmd)) {// dump service state}// ... and so on for many other arguments} else {// default dump logic if no arguments are provided}}
}

ActivityManagerServicedump 方法中,我们可以看到:

  • 权限检查:首先会检查调用者是否拥有 android.Manifest.permission.DUMP 权限。这解释了为什么我们通常需要通过 adb shell 来执行 dumpsys,因为 shell 用户默认拥有这个权限。
  • 参数解析dump 方法会解析 args 字符串数组,根据不同的参数执行不同的 dump 逻辑。例如,如果第一个参数是 activitiesa,它就会输出 Activity 的堆栈信息。
  • 信息输出:通过传入的 PrintWriter pw 对象,将服务的状态信息格式化为字符串并输出。

三、adb dump 的使用

3.1 adb dumpsys 的基本语法

adb shell dumpsys [service_name] [arguments]

常用命令示例

  • 列出所有可 dump 的服务

    adb shell dumpsys -l
    
  • 查看 Activity 管理器信息

    adb shell dumpsys activity
    

    这个命令会输出非常多的信息,包括 Activity 堆栈、正在运行的服务、广播队列等。

  • 查看窗口管理器信息

    adb shell dumpsys window
    

    可以用来查看当前窗口的层级、焦点窗口、Surface 信息等,对于分析 UI 问题非常有帮助。

  • 查看内存使用情况

    adb shell dumpsys meminfo <package_name>
    

    可以获取指定应用的详细内存使用情况,是排查内存泄漏的重要工具。

  • 查看电池状态

    adb shell dumpsys batterystats
    

    提供详细的电池使用统计信息,帮助分析应用的耗电情况。

3.2 如何根据源码使用 adb 查看对应信息

掌握 dumpsys 的精髓在于学会如何通过阅读源码来发现其强大的功能。下面我们通过一个实例来演示这个过程。

目标:我们想知道 ActivityManagerService 中最近的任务(Recent Tasks)列表。

步骤

  1. 定位到 ActivityManagerServicedump 方法
    我们已经知道其路径在 frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

  2. dump 方法中寻找与“最近任务”相关的代码
    通过在 dump 方法中搜索关键词 “recent”,我们可以找到类似如下的代码:

    // In ActivityManagerService.java's dump method} else if ("recents".equals(cmd) || "r".equals(cmd)) {// dump recent activities
    }
    

    从这段代码我们可以推断出,要 dump 最近的任务列表,我们可以使用 recents 或者其缩写 r 作为 dumpsys activity 的参数。

  3. 构造并执行 adb 命令
    根据上面的发现,我们可以在命令行中执行:

    adb shell dumpsys activity recents
    

    或者使用缩写:

    adb shell dumpsys activity r
    
  4. 分析输出结果
    执行上述命令后,你将会看到一个包含了最近任务信息的列表,其中有每个任务的 ID、关联的 Activity、Intent 等详细信息。

通过这个简单的例子,你可以举一反三,探索其他系统服务的 dump 方法,发现更多有用的调试选项。例如,你可以在 WindowManagerServicedump 方法中寻找与特定窗口或 Display 相关的 dump 选项,从而实现更精细化的 UI 调试。

四、总结

Android 的 dump 机制是一个功能强大且设计精巧的系统诊断工具。通过 adb dumpsys,开发者可以深入到系统的每一个角落,获取到宝贵的状态信息。理解其基于 Binder 的工作原理和核心代码实现,不仅能够帮助我们更有效地使用这个工具,更能加深我们对 Android 系统架构的理解。

更重要的是,通过将源码阅读与 adb 命令实践相结合,你将能够解锁 dumpsys 的全部潜力,成为一名更出色的 Android 系统开发者和调试专家。希望这篇博客能够为你打开一扇通往 Android 系统底层世界的大门。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/94792.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/94792.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt数据结构与编码技巧全解析

文章目录Qt中的数据结构QDebugqDebug函数QT的内置类型一般都会重载 << 运算符QT的几何规则QString 字符串编码变长 VS 定长QString 适合中转数据吗&#xff1f;Qstring 的底层使用写时复制QString的具体使用QString 的构造函数格式化构造数值转化为字符串字符串转成数值增…

Ubuntu操作系统下MySQL、MongoDB、Redis

在开发和运维过程中&#xff0c;经常需要从Windows客户端远程连接到Ubuntu服务器上的数据库。本文将详细介绍如何在Ubuntu操作系统下安装和配置MySQL、MongoDB和Redis&#xff0c;以允许从Windows客户端进行远程连接&#xff0c;并提供详细的远程连接命令和配置说明。一、MySQL…

校园勤工俭学微信小程序的设计与实现:基于数字化服务生态的赋能体系构建

在高等教育普及化与数字化校园建设的双重驱动下&#xff0c;传统校园勤工俭学管理模式正面临深刻变革。当前高校勤工俭学工作普遍存在岗位匹配效率低下、过程管理粗放、数据孤岛严重等痛点——根据教育部全国学生资助管理中心2022年统计数据&#xff0c;全国普通高校共有约450万…

Apisix工作流程

是的,你的理解基本正确:当请求到达APISIX时,它会先根据请求的URI、Host、请求方法、 headers等信息匹配最合适的路由,然后执行路由关联的插件逻辑,最后转发到路由配置的上游服务。下面详细讲解APISIX处理请求的全链路及可能的情况。 一、请求全链路流程 APISIX处理请求的…

InnoDB存储引擎底层拆解:从页、事务到锁,如何撑起MySQL数据库高效运转(上)

目录 Page页** B树查询 如何加快记录的查询&#xff1f; 索引** 聚簇索引(主键) 二级索引(非主键) 联合索引——多列 bufferPool* Free链表 flush链表 Flush链表刷新方式有如下两种&#xff1a; LRU链表 针对LRU链表方案缺点的优化 redoLog* redo简单日志类型 redo复杂日志类型…

【人工智能99问】GPT4的原理是什么?(32/99)

【人工智能99问】GPT4的原理是什么&#xff1f;(32/99) 文章目录GPT-4简介一、结构与原理二、使用场景三、优缺点分析四、训练技巧与关键改进五、示例说明六、总结GPT-4简介 一、结构与原理 1. 架构设计 GPT-4基于Transformer解码器架构&#xff0c;核心改进包括&#xff1a;…

//Q是一个队列,S是一个空栈,实现将队列中的元素逆置的算法。

#include<stdio.h> #include<stdbool.h> #include<stdlib.h> #define Size 6 typedef struct SqNode//队列结点 {int data;struct SqNode* next; }LinkNode; typedef struct SqQueue//队列 {LinkNode* front, * rear; //头指针和尾指针 }LinkQueue; typedef …

毕马威 —— 公众对人工智能的信任、态度及使用情况调查

文章目录 前言 一、背景介绍 二、对人工智能的信任与接受度 三、人工智能的使用与认知情况 四、人工智能的益处与风险 五、人工智能的监管与治理 六、工作场所的人工智能应用 七、人工智能对工作的影响 八、学生对人工智能的应用 九、核心启示 1.新兴经济体在公众与员工人工智能…

基于Spring Session + Redis + JWT的单点登录实现

实现思路 用户访问受保护资源时&#xff0c;若未认证则重定向到认证中心认证中心验证用户身份&#xff0c;生成JWT令牌并存储到Redis认证中心重定向回原应用并携带令牌应用验证JWT有效性并从Redis获取会话信息用户在其他应用访问时&#xff0c;通过相同机制实现单点登录 代码…

微服务Eureka组件的介绍、安装、使用

微服务 Eureka 组件的介绍、安装与使用详解 在微服务架构中&#xff0c;服务注册与发现是至关重要的一环&#xff0c;而 Eureka 作为 Netflix 开源的服务注册中心&#xff0c;广泛应用于 Spring Cloud 微服务体系中。本文将带你全面了解 Eureka 的概念、安装及在 Spring Boot …

【PostgreSQL内核学习:通过 ExprState 提升哈希聚合与子计划执行效率(一)】

PostgreSQL内核学习&#xff1a;通过 ExprState 提升哈希聚合与子计划执行效率&#xff08;一&#xff09;引言背景补丁的意义补丁概述JIT & LLVM实际例子&#xff08;以 PostgreSQL 为例&#xff09;提交信息提交描述引入 ExprState 进行哈希计算&#xff1a;支持 JIT 编译…

web端播放flv视频流demo(flv.js的使用)

需求&#xff1a;原本是需要前端播放RTMP视频流的&#xff0c;但是现在的浏览器都不支持flash插件了&#xff0c;让用户安装flash插件也不现实&#xff0c;所以直接让后端将RTMP视频流转换成flv视频流给到前端进行播放。 直接上demo&#xff0c;直接就能播放&#xff0c;如果遇…

【拍摄学习记录】04-拍摄模式/曝光组合

曝光组合全自动半自动光圈优先手动挡【固定物体长时间不变时候、闪光灯时候、】手机上的光学变焦与数码变焦是不同的&#xff0c;使用档位推荐可以提升画质。手机夜景模式长曝光【车流轨迹、星轨】HDR 大光比【日落时候使用】专业模式&#xff0c;【感光度iso、快门可以调节】…

新liunx部署mysql过程问题

首先看下是什么发行版 cat /etc/os-release CentOS Linux 7 ################################## 使用 yum下载包 发现不行 源不行 那就换成阿里的 # 进入 yum 源配置目录 cd /etc/yum.repos.d/ # 备份所有默认 repo 文件&#xff08;以 CentOS 为例&#xff0c;其他系统…

Python 第三方库:Beautiful Soup(HTML/XML 解释提取)

Beautiful Soup 是一个 用于从 HTML 和 XML 文件中提取数据的 Python 第三方库。它为复杂的网页结构提供了简单易用的解析接口&#xff0c;尤其适合网页爬虫和数据提取任务。Beautiful Soup 提供树型结构访问、标签搜索、属性提取等功能&#xff0c;并支持多种解析器&#xff0…

使用STM32CubeMX使用CAN驱动无刷电机DJI3508

简介 文章为笔记性质 硬件包括 大疆C板 电机调速器C620 DJI3508电机 CAN知识介绍 CAN的概念 CAN是控制器区域网络&#xff08;Controller Area Network&#xff09;的缩写。CAN总线是一种适用于工业设备的高性能总线网络。说白了就是也就是一种通讯方式而已。 把多个设…

Wi-Fi 802.11s自组网/EasyMesh自组网/802.11ah物联网

一、前期调研结论 前面详细探讨了自组网和5G无线通信网络、WiFi无线通信网络的差异&#xff1a; 自组网 v.s 5G v.s WiFi-CSDN博客 从“分级道路”角度理解无线通信网络拓扑包括从当前工业应用场景具体案例了解终端无线通信网络&#xff1a; 5G无线通信网络场景&#xff08;…

【基于hyperledger fabric的教育证书管理系统】

教育证书管理系统 系统概述 项目背景 随着数字化转型的深入推进&#xff0c;教育证书作为个人学术成就和专业资质的重要凭证&#xff0c;在就业市场、高等教育和职业发展中扮演着关键角色。然而&#xff0c;传统教育证书管理体系面临着数据孤岛、证书伪造、验证流程繁琐以及跨机…

【Flask】测试平台开发,集成禅道

概述&#xff1a; 由于公司多数测试人员还是在使用禅道&#xff0c;为了方便&#xff0c;就将禅道直接集成在我们的测试平台中 一般可以有几种实现方法 调用禅道的API集成集成本地部署的禅道-可能有跨域问题&#xff0c;需要解决 由于我这里已经部署了一台本地的禅道系统&…

《UE5_C++多人TPS完整教程》学习笔记45 ——《P46 待机与跳跃(Idle And Jumps)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P46 待机与跳跃&#xff08;Idle And Jumps&#xff09;》 的学习笔记&#xff0c;该系列教学视频为计算机工程师、程序员、游戏开发者、作家&#xff08;Engineer, Programmer, Game Developer, Author&#xff09; St…