尊重原创,转载请注明出处!
创作不易,如有帮助请点赞支持~
引言
dumpsys 是 Android 系统中的一个可执行程序,可以用于查询系统状态、定位问题,调试过程中经常会用到。
常见用法
指令 | 作用 |
---|---|
dumpsys -l | 列举所有支持 dumpsys 指令的服务 |
dumpsys activity top | 查询最上层的应用 |
dumpsys media.camera | 查询 Camera 的信息和使用情况 |
dumpsys meminfo | 查看内存使用情况 |
dumpsys display | 查看显示设备相关信息 |
dumpsys input | 可以查看当前加载按键的 kl 文件等 |
dumpsys window displays | 获取屏幕分辨率 |
dumpsys package xxx | 查看指定的应用详情 |
…
dumpsys 的用法太多了,没法一一列举,只能列举自己在开发过程中经常遇到的一些指令。更多的用法,可以通过执行 dumpsys -help 可以返回它的使用方法:
XXX:/ # dumpsys -h
dumpsys: invalid option -- h
usage: dumpsys
To dump all services.
or:
dumpsys [-t TIMEOUT] [--priority LEVEL] [--help | -l | --skip SERVICES | SERVICE [ARGS]]
--help: shows this help
-l: only list services, do not dump them
-t TIMEOUT_SEC: TIMEOUT to use in seconds instead of default 10 seconds
-T TIMEOUT_MS: TIMEOUT to use in milliseconds instead of default 10 seconds
--proto: filter services that support dumping data in proto format. Dumps
will be in proto format.
--priority LEVEL: filter services based on specified priority
LEVEL must be one of CRITICAL | HIGH | NORMAL
--skip SERVICES: dumps all services but SERVICES (comma-separated list)
SERVICE [ARGS]: dumps only service SERVICE, optionally passing ARGS to it
源码分析
dumpsys 源码位于 /frameworks/native/cmds/dumpsys/ 下,主要逻辑都在 dumpsys.cpp 中。关键代码如下:
int Dumpsys::main(int argc, char* const argv[]) {
......
for (size_t i = 0; i < N; i++) {
String16 service_name = std::move(services[i]);
if (IsSkipped(skippedServices, service_name)) continue;
// 找到相应的服务
sp<IBinder> service = sm_->checkService(service_name);
if (service != nullptr) {
......
// dump blocks until completion, so spawn a thread..
std::thread dump_thread([=, remote_end { std::move(remote_end) }]() mutable {
// 调用对应服务的dump方法,并将参数传递
int err = service->dump(remote_end.get(), args);
// It'd be nice to be able to close the remote end of the socketpair before the dump
// call returns, to terminate our reads if the other end closes their copy of the
// file descriptor, but then hangs for some reason. There doesn't seem to be a good
// way to do this, though.
remote_end.reset();
if (err != 0) {
aerr << "Error dumping service info: (" << strerror(err) << ") " << service_name
<< endl;
}
});
......
} else {
aerr << "Can't find service: " << service_name << endl;
}
}
return 0;
}
所以,执行 dumpsys [service] 时,其实就是查询到对应的服务后,再通过 binder 调用到对应服务的 dump 方法。
在查看源码的时候,经常会看到一些系统服务中有一个 dump 方法,里面有各种各样调试的代码,之前一直在想这个方法是怎么调用的,现在看了 dumpsys 的实现后,就很清晰明了了~