DiskStatsService和DeviceStorageMonitorService两个服务都和系统内部存储管理、监控有关。
这里先讲DiskStatsService
DiskStatsService
DiskStatsService很简单,代码只有100行左右,它直接继承自Binder,却没有实现Binder的任何接口:
/**
* This service exists only as a "dumpsys" target which reports
* statistics about the status of the disk.
*/
public class DiskStatsService extends Binder {
根据源码注释,这个Service只是在执行 dumpsys命令时输出存储设备的使用情况。
说到dumpsys命令,这是系统中一个很重要的命令,主要用于打印系统中指定服务, 它是用C++写的,在dumpsys.cpp文件中,我们看一下它的main方法:
int main(int argc, char* const argv[])
{
//先得到与ServiceManager通信的 BpServiceManager
sp<IServiceManager> sm = defaultServiceManager();
...
Vector<String16> services;
Vector<String16> args;
bool showListOnly = false;
if ((argc == 2) && (strcmp(argv[1], "-l") == 0)) {
showListOnly = true;
}
if ((argc == 1) || showListOnly) {
//如果参数只有一个,或者参数里写了 -l, 就查询在ServiceManager中注册的所有Service
services = sm->listServices();
services.sort(sort_func);//将service排序
args.add(String16("-a"));
} else {
//查询指定的某个Service
services.add(String16(argv[1]));
for (int i=2; i<argc; i++) {
//保存剩余其他参数,用于后面传递给这个Service的 dump函数
args.add(String16(argv[i]));
}
}
const size_t N = services.size();
...
for (size_t i=0; i<N; i++) {
sp<IBinder> service = sm->checkService(services[i]);
if (service != NULL) {
...
//将上面剩余的参数传递给这个service
int err = service->dump(STDOUT_FILENO, args);
...
}
return 0;
}
从上面代码可知, dumpsys通过Binder 调用Service的dump函数,打印出相关信息。
而其中有一个命令,就是 dumpsys diskstats, 这个命令就是调用DiskStatsService的dump命令。因为在SystemServer中添加代码如下:
ServiceManager.addService("diskstats", new DiskStatsService(context));
可以看到, DiskStatsService添加到ServiceManager后,这个服务的名字就是 diskstats。 所以 dumpsys diskstats执行的就是DiskStatsService的dump命令, 执行的效果如下:
这个命令打印了系统内部存储的使用情况。 上述测试是在华为荣耀7手机上进行的测试。
DiskStatsService的dump函数
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
//先运行一组512的脏数据,快速进行性能测试
//输出 /data/system/perftest.tmp文件信息,这个文件看名字应该是和性能测试有关。
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");
FileOutputStream fos = null;
IOException error = null;
long before = SystemClock.uptimeMillis();
try {
fos = new FileOutputStream(tmp);
fos.write(junk);
} catch (IOException e) {
error = e;
} finally {
try { if (fos != null) fos.close(); } catch (IOException e) {}
}
long after = SystemClock.uptimeMillis();
if (tmp.exists()) tmp.delete();
if (error != null) {
pw.print("Test-Error: ");
pw.println(error.toString());
} else {
pw.print("Latency: ");
pw.print(after - before);
pw.println("ms [512B Data Write]");
}
//打印内部存储设备各分区的使用情况
reportFreeSpace(Environment.getDataDirectory(), "Data", pw);
reportFreeSpace(Environment.getDownloadCacheDirectory(), "Cache", pw);
reportFreeSpace(new File("/system"), "System", pw);
// 部分厂商会打印 /proc/yaffs 信息
//厂商还会根据需要打印其他感兴趣的信息
// 甚至根据需要添加 dumpsys 命令参数,传递给此dump函数
}
从以上代码可以看到,DiskStatsService主要就是用来执行dumpsys命令,打印内部存储信息。
总结
DiskStatsService代码很简单,另一个DeviceStorageManagerService也是和存储有关的服务, 不知道Google是什么考虑,两个没有何在一起。看起来DiskStatsService主要是用来进行调试使用。 下一篇将讲到DeviceStorageManagerService。
参考《深入理解Android》
分析源码为(android 22)