dumpsys是Android系统中的一个可执行文件,主要作用是将当前Android系统的一些信息dump出来,例如Activity、package等。是一个分析Android设备问题、查看运行状态、使用情况等十分有效的工具。可以获取各种系统信息和状态,如进程的PSS值,分析了解进程对RAM的占用情况。
dumpsys的语法提供了灵活的方式来获取和分析Android系统中各种服务的信息。基本语法结构如下:
adb shell dumpsys [-t timeout] [--help | -l | --skipservices | service[arguments] | -c | -h]
- [-t timeout]:可选参数,用于指定命令执行的超时时间(以秒为单位)。默认为10秒。
- [--help | -l | --skipservices | service[arguments] | -c | -h]:命令行选项,用于定制dumpsys的输出和行为。
--help:打印dumpsys的使用方法说明。
-l:列出dumpsys支持的所有系统服务列表。
--skipservices:指定不需要打印的服务列表。
service[arguments]:指定要查询的特定服务及其可选参数。通过指定服务名称,可以获取特定服务的详细信息。
-c:以机器友好的格式(通常是键值对)输出信息,对于自动化脚本解析可能很有用,对于人类阅读可能不太友好。
-h:用在指定的服务后面,打印服务支持哪些参数或如何使用该服务。
% adb shell dumpsys -l Currently running services: DisplayFeatureControl DockObserver MiuiBackup MiuiCarService MiuiInit MiuiWifiService ProcessManager SchedBoostService SlaveWifiService SurfaceFlinger accessibility account activity activity_task adb
如果dumpsys不加任何参数,会输出所有系统服务的详细信息,输出的内容是非常多的。实际解决具体问题时,我们通常只关注一些特定系统服务的输出,只需要将服务名作为dumpsys命令的参数,就可以只输出特定服务的信息。比如要输出磁盘使用的统计信息,则可以将diskstats这个系统服务名作为参数。
% adb shell dumpsys diskstats Latency: 1ms [512B Data Write] Recent Disk Write Speed (kB/s) = 45546 Data-Free: 53243072K / 113006560K total = 47% free Cache-Free: 53243072K / 113006560K total = 47% free System-Free: 0K / 5192648K total = 0% free File-based Encryption: true App Size: 16656406016 App Data Size: 33915740160 App Cache Size: 2662189568 Photos Size: 77041664 Videos Size: 17559552 Audio Size: 38887424 Downloads Size: 0 System Size: 128000000000 Other Size: 9238536192
工作原理
dumpsys基于Android系统的服务管理和进程间通信机制。通过调用Android系统底层的ServiceManager服务,来获取系统中所有已注册服务的信息。ServiceManager是Android系统中的一个核心服务,负责管理系统中的所有服务,提供统一的注册、发现和通信机制。
当dumpsys被调用时,会通过Binder进程间通信(IPC)框架与ServiceManager进行交互。Binder是Android提供的一套进程间相互通信的框架,允许不同的进程之间进行高效的通信和数据交换。通过Binder,dumpsys能够请求ServiceManager提供当前系统中所有已注册服务的列表,以及每个服务的详细信息。
ServiceManager会响应dumpsys的请求,返回系统中所有服务的状态信息。包括服务的名称、状态、运行时的统计数据等。dumpsys接收到这些信息后,会进行解析和整理,并以一种可读的方式展示。
int main(int argc, char* const argv[]) { ... // 1. 首先获取 servicemanager sp<IServiceManager> sm = defaultServiceManager(); ... // 2. 进行命令行参数解析 bool showListOnly = false; if ((argc == 2) && (strcmp(argv[1], "-l") == 0)) { // 2.1 当参数仅为 "-l" 时,设置只罗列出所有的服务名 showListOnly = true; } if ((argc == 1) || showListOnly) { // 2.2 当不带任何参数时,则附加 "-a" 参数,表示输出所有系统服务信息 services = sm->listServices(); services.sort(sort_func); args.add(String16("-a")); } else { // 2.3 当带了一个参数时,表示仅输出指定的系统服务信息 services.add(String16(argv[1])); for (int i=2; i<argc; i++) { args.add(String16(argv[i])); } } // 3. 罗列出services这个数组中的服务名称,到这一步为止,都还只是在dumpsys本身的逻辑中转悠 const size_t N = services.size(); if (N > 1) { aout << "Currently running services:" << endl; for (size_t i=0; i<N; i++) { sp<IBinder> service = sm->checkService(services[i]); if (service != NULL) { aout << " " << services[i] << endl; } } } if (showListOnly) { return 0; } // 4. 输出services这个数组中所包含系统服务的详细信息 for (size_t i=0; i<N; i++) { sp<IBinder> service = sm->checkService(services[i]); if (service != NULL) { ... // 4.1 调用service的dump方法,来输出service的具体信息 int err = service->dump(STDOUT_FILENO, args); ... } ... } return 0; }
- 获取servicemanager,所有的系统服务都会向servicemanager注册
- 进行命令行参数解析,根据参数的不同设置后续的执行指令序列
- 简单的罗列了一下需要输出的系统服务名称
- 调用具体系统服务的dump()方法完成系统服务详细信息的输出
以上面adb shell dumpsys diskstats命令为例,最终调用dump()方法完成输出:
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { // 1. 权限检查 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); // 2. 生成一个大小为512B的临时文件 byte[] junk = new byte[512]; for (int i = 0; i < junk.length; i++) junk[i] = (byte) i; // Write nonzero bytes File tmp = new File(Environment.getDataDirectory(), "system/perftest.tmp"); // 3. 将512B的临时文件写入磁盘,目的是为了快速的测试写磁盘的延迟 long before = SystemClock.uptimeMillis(); ... fos = new FileOutputStream(tmp); fos.write(junk); ... long after = SystemClock.uptimeMillis(); ... pw.print("Latency: "); pw.print(after - before); pw.println("ms [512B Data Write]"); ... // 4. 输出Data, Cache和System这几个分区的磁盘使用信息 reportFreeSpace(Environment.getDataDirectory(), "Data", pw); reportFreeSpace(Environment.getDownloadCacheDirectory(), "Cache", pw); reportFreeSpace(new File("/system"), "System", pw); .... }
原文地址:https://mp.weixin.qq.com/s/k-SSAmPTNekzJjaG5mTBQQ