3.5.2 DeviceStorageManagerService分析
DeviceStorageManagerService(DSMS)是用来监测系统内部存储空间的状态的,添加该服务的代码如下:
//DSMS的服务名为devicestoragemonitor
ServiceManager.addService(DeviceStorageMonitorService.SERVICE,
new DeviceStorageMonitorService(context));
DSMS的构造函数的代码如下:
[—>DeviceStorageManagerService.java:DeviceStorageMonitorService]
public DeviceStorageMonitorService(Context context){
mLastReportedFreeMemTime=0;
mContext=context;
mContentResolver=mContext.getContentResolver();
mDataFileStats=new StatFs(DATA_PATH);//获取data分区的信息
mSystemFileStats=new StatFs(SYSTEM_PATH);//获取system分区的信息
mCacheFileStats=new StatFs(CACHE_PATH);//获取cache分区的信息
//获得data分区的总大小
mTotalMemory=((long)mDataFileStats.getBlockCount()*
mDataFileStats.getBlockSize())/100L;
/*
创建3个Intent,分别用于通知存储空间不足、存储空间恢复正常和存储空间满。
由于设置了REGISTERED_ONLY_BEFORE_BOOT标志,这3个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);
//查询Settings数据库中sys_storage_threshold_percentage的值,默认是10,
//即当/data空间只剩下10%的时候,认为空间不足
mMemLowThreshold=getMemThreshold();
//查询Settings数据库中的sys_storage_full_threshold_bytes的值,默认是1MB,
//即当data分区只剩1MB时,就认为空间已满,剩下的这1MB空间保留给系统自用
mMemFullThreshold=getMemFullThreshold();
//检查内存
checkMemory(true);
}
再来看checkMemory函数,其实现代码如下:
[—>DeviceStorageManagerService.java:checkMemory]
private final void checkMemory(boolean checkCache){
if(mClearingCache){
……//如果正在清理空间,则不作处理
}else{
restatDataDir();//重新计算3个分区的剩余空间大小
//如果剩余空间低于mMemLowThreshold,那么先清理一次空间
clearCache();
//如果空间仍不足,则发送广播,并在状态栏上设置一个警告通知
sendNotification();
……
//如果空间已满,则调用下面这个函数,以发送一次存储已满的广播
sendFullNotification();
}……
//DEFAULT_CHECK_INTERVAL为1分钟,即每1分钟会触发一次检查
postCheckMemoryMsg(true, DEFAULT_CHECK_INTERVAL);
}
当空间不足时,DSMS会先尝试clearCache函数,该函数内部会与PackageManager-Service(以下简称PKMS)交互,其代码如下:
[—>DeviceStorageManagerService.java:clearCache]
private final void clearCache(){
if(mClearCacheObserver==null){
//创建一个CachePackageDataObserver对象,当PKMS清理完空间时会回调该对象的
//onRemoveCompleted函数
mClearCacheObserver=new CachePackageDataObserver();
}
mClearingCache=true;//设置mClearingCache的值为true,表示我们正在清理空间
try{
//调用PKMS的freeStorageAndNotify函数以清理空间,这个函数在分析PKMS时再介绍
IPackageManager.Stub.asInterface(
ServiceManager.getService("package")).
freeStorageAndNotify(mMemLowThreshold, mClearCacheObserver);
}……
}
CachePackageDataObserver是DSMS定义的内部类,其onRemoveCompleted函数很简单,就是重新发送消息,让DSMS再检测一次存储空间。
DeviceStorageManagerService的功能单一,没有重载dump函数。而DiskStats-Service唯一有用的就是dump功能了。不知Google的工程师为什么没有把DeviceStorage-ManagerService和DiskStatsService的功能整合到一起。