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的功能整合到一起。