DiskStatsService和DeviceStorageMonitorService兩個服務都和系統内部存儲管理、監控有關。
這一篇繼續學習DeviceStorageMonitorService(以下簡稱DSMS)。
DeviceStorageMonitorService和DeviceStorageManagerService是一個東西,隻是在5.0以後,名字改為了DeviceStorageMonitorService。
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<SystemService> serviceClass;
try {
serviceClass = (Class<SystemService>)Class.forName(className);
}
...
return startService(serviceClass);
}
public <T extends SystemService> T startService(Class<T> serviceClass) {
...
final T service;
try {
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance
...
// 注冊到ServiceManager中
mServices.add(service);
try {
service.onStart();//啟動服務
}
...
}
其實就是用過反射擷取執行個體,然後将Service注冊添加到ServiceManager中, 最後調用了DSMS的onStart方法,那接下來就看看DSMS的構造方法 以及 onStart方法。
DeviceStorageMonitorService的構造方法
我們看看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);
}
可以看到,構造方法就是初始化一些資料,拿到内部儲存設備的一些資訊。
onStart方法啟動服務
代碼如下:
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方法。
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》