DiskStatsService和DeviceStorageMonitorService两个服务都和系统内部存储管理、监控有关。
这一篇继续学习DeviceStorageMonitorService(以下简称DSMS)。
DeviceStorageMonitorService和DeviceStorageManagerService是一个东西,只是在5.0以后,名字改为了DeviceStorageMonitorService。
在SystemServer进程中的添加此服务的代码如下:
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
...
mSystemServiceManager.startService(DeviceStorageMonitorService.class);
通过SystemServiceManager的startService方法启动了DSMS,看一下这个startService方法做了什么:
public SystemService startService(String className) {
final Class serviceClass;
try {
serviceClass = (Class)Class.forName(className);
}
...
return startService(serviceClass);
}
public T startService(Class serviceClass) {
...
final T service;
try {
Constructor constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance
...
// 注册到ServiceManager中
mServices.add(service);
try {
service.onStart();//启动服务
}
...
}
其实就是用过反射获取实例,然后将Service注册添加到ServiceManager中, 最后调用了DSMS的onStart方法,那接下来就看看DSMS的构造方法 以及 onStart方法。
我们看看DSMS的构造方法里都做了些什么:
public DeviceStorageMonitorService(Context context) {
super(context);
mLastReportedFreeMemTime = 0;
mResolver = context.getContentResolver();
mIsBootImageOnDisk = isBootImageOnDisk();
//create StatFs object
mDataFileStats = new StatFs(DATA_PATH.getAbsolutePath());//获取data分区的信息
//获取system分区的信息
mSystemFileStats = new StatFs(SYSTEM_PATH.getAbsolutePath());
//获取cache分区的信息
mCacheFileStats = new StatFs(CACHE_PATH.getAbsolutePath());
//获取data分区的总大小
mTotalMemory = (long)mDataFileStats.getBlockCount() *
mDataFileStats.getBlockSize();
//创建intent, 分别通知存储空间不足、存储空间回复正常、
//存储空间已满、存储空间不满等状态
mStorageLowIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_LOW);
mStorageLowIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mStorageOkIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_OK);
mStorageOkIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mStorageFullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_FULL);
mStorageFullIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mStorageNotFullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_NOT_FULL);
mStorageNotFullIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
}
可以看到,构造方法就是初始化一些数据,拿到内部存储设备的一些信息。
代码如下:
public void onStart() {
// 缓存设定的阈值
final StorageManager sm = StorageManager.from(getContext());
mMemLowThreshold = sm.getStorageLowBytes(DATA_PATH);
mMemFullThreshold = sm.getStorageFullBytes(DATA_PATH);
mMemCacheStartTrimThreshold = ((mMemLowThreshold*3)+mMemFullThreshold)/4;
mMemCacheTrimToThreshold = mMemLowThreshold
+ ((mMemLowThreshold-mMemCacheStartTrimThreshold)*2);
mFreeMemAfterLastCacheClear = mTotalMemory;
//检查内存
checkMemory(true);
...
}
也是对一部分值的初始化,然后主要调用了checkMemory方法检查内存:
void checkMemory(boolean checkCache) {
if(mClearingCache) {
...//如果正在清理存储空间,则不作处理
} else {
restatDataDir();//重新计算三个分区的剩余空间
if (mFreeMem < mMemLowThreshold) {
...
if(checkCache) {
...//如果剩余空间低于mMemLowThreshold,那就先清理一次空间
clearCache(); // 代码 1111111
else {
//如果剩余空间任不足,则发送广播,并在状态栏设置警告
sendNotification();
mLowMemFlag = true;
...
} else {
if (mLowMemFlag) {
//存储空间还够用,则取消警告
cancelNotification();
mLowMemFlag = false;
}
}
if (mFreeMem < mMemFullThreshold) {
if (!mMemFullFlag) {
//如果空间已满,则发送存储已满的广播
sendFullNotification();
}
}
//DEFAULT_CHECK_INTERVAL为一分钟,每分钟触发一次检查。
postCheckMemoryMsg(true, DEFAULT_CHECK_INTERVAL);
}
在上述 代码11111中,我们看到,当存储不足时,就会调用清理缓存clearCache方法。
当空间不足,需要清理时, DSMS会调用clearCache, 这个方法内部会和PackageManagerService交互
private void clearCache() {
if (mClearCacheObserver == null) {
//创建一个Observe
mClearCacheObserver = new CachePackageDataObserver();
}
mClearingCache = true;
try {
//调用PackageManagerService的清理存储空间方法freeStorageAndNotify
IPackageManager.Stub.asInterface(ServiceManager.getService("package")).
freeStorageAndNotify(null, mMemCacheTrimToThreshold, mClearCacheObserver);
} catch (RemoteException e) {
...
}
}
packageManagerService添加在ServiceManager中时,名字就是“package”, 通过PackageManagerService的freeStorageAndNotify方法清理存储, 这个会在后面分析PackageManagerService时继续分析。
DeviceStorageMonitorService 也比较简单,没有太多功能,本身没有重载dump函数, 而DiskStatsService仅仅只是重载了dump函数,不知道Google为什么没有将他们整合为一个Service。
参考《深入理解Android》