DeviceStorageManagerService部分源码:
/*
DeviceStorageManagerService构造方法
*/
public DeviceStorageManagerService(Context context)
{
mLastReportedFreeMemTime = 0;
mContext = context;
/*
数据共享
*/
mContentResolver = mContext.getContentResolver();
/*
获取data分区信息
*/
mDataFileStats = new StatFs(DATA_PATH);
/*
获取System分区信息
*/
mSystemFileStats = new StatFs(SYSTEM_PATH);
/*
获取Cache信息
*/
mCacheFileStats = new StatFs(CACHE_PATH);
/*
获得data分区的总大小
*/
mTotalMemory = ((long)mDataFileStats.getBlockCount() * mDataFileStats.getBlockSize()) / 100L;
/*
Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFOR_BOOT
在boot完成前发送广播,只能由系统服务接收
*/
/*
用于通知存储空间不足
*/
mStorageLowIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_LOW);
mStorageLoaIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFOR_BOOT);
/*
用于通知存储空间恢复正常
*/
mStorageOkIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_OK);
mStorageOkIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFOR_BOOT);
/*
存储空间满
*/
mStorageFullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_FULL);
mStorageFullIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFOR_BOOT);
mStorageNotFullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_NOT_FULL);
mStorageNotFullIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFOR_BOOT);
/*
Threshold: 极限
查询Settings数据库中sys_storage_threshold_percentage的值,默认值是10%,
当data空间只剩下10%的时候,认为空间不足
*/
mMemLowThreshold = getMemThreshold();
/*
查询Settings数据库中sys_storage_full_threshold_bytes的值,默认是1MB
当data空间只剩1MB时,就认为空间已满,剩下1MB供系统使用
*/
mMemFullThreshold = getMemFullThreshold();
/*
检查内存
*/
checkMemory(true);
}
private final void checkMemory(boolean checkCache) {
//if the thread that was started to clear cache is still running do nothing till its
//finished clearing cache. Ideally this flag could be modified by clearCache
// and should be accessed via a lock but even if it does this test will fail now and
//hopefully the next time this flag will be set to the correct value.
/*
如果正在清理,则不作处理
*/
if(mClearingCache) {
if(localLOGV) Slog.i(TAG, "Thread already running just skip");
//make sure the thread is not hung for too long
long diffTime = System.currentTimeMillis() - mThreadStartTime;
if(diffTime > (10*60*1000)) {
Slog.w(TAG, "Thread that clears cache file seems to run for ever");
}
} else {
/*
重新计算3个分区的大小
*/
restatDataDir();
if (localLOGV) Slog.v(TAG, "freeMemory="+mFreeMem);
//post intent to NotificationManager to display icon if necessary
if (mFreeMem < mMemLowThreshold) {
if (!mLowMemFlag) {
if (checkCache) {
// See if clearing cache helps
// Note that clearing cache is asynchronous and so we do a
// memory check again once the cache has been cleared.
mThreadStartTime = System.currentTimeMillis();
mClearSucceeded = false;
/*
尝试清除缓存
*/
clearCache();
} else {
Slog.i(TAG, "Running low on memory. Sending notification");
/*
清除后,空间仍不足,发送广播
*/
sendNotification();
mLowMemFlag = true;
}
} else {
if (localLOGV) Slog.v(TAG, "Running low on memory " +
"notification already sent. do nothing");
}
} else {
if (mLowMemFlag) {
Slog.i(TAG, "Memory available. Cancelling notification");
cancelNotification();
mLowMemFlag = false;
}
}
if (mFreeMem < mMemFullThreshold) {
if (!mMemFullFlag) {
/*
如果空间已满,发送存储已满广播
*/
sendFullNotification();
mMemFullFlag = true;
}
} else {
if (mMemFullFlag) {
cancelFullNotification();
mMemFullFlag = false;
}
}
}
if(localLOGV) Slog.i(TAG, "Posting Message again");
//keep posting messages to itself periodically
/*
private static final long DEFAULT_CHECK_INTERVAL = MONITOR_INTERVAL*60*1000;
默认检查时间为1分钟
*/
postCheckMemoryMsg(true, DEFAULT_CHECK_INTERVAL);
}
清理缓存涉及的部分源代码:
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
//don't handle an invalid message
if (msg.what != DEVICE_MEMORY_WHAT) {
Slog.e(TAG, "Will not process invalid message");
return;
}
/*
收到后checkMemory
*/
checkMemory(msg.arg1 == _TRUE);
}
};
private void postCheckMemoryMsg(boolean clearCache, long delay) {
// Remove queued messages
mHandler.removeMessages(DEVICE_MEMORY_WHAT);
/*
发送消息给handler
*/
mHandler.sendMessageDelayed(mHandler.obtainMessage(DEVICE_MEMORY_WHAT,
clearCache ?_TRUE : _FALSE, 0),
delay);
}
class CachePackageDataObserver extends IPackageDataObserver.Stub {
public void onRemoveCompleted(String packageName, boolean succeeded) {
mClearSucceeded = succeeded;
mClearingCache = false;
if(localLOGV) Slog.i(TAG, " Clear succeeded:"+mClearSucceeded
+", mClearingCache:"+mClearingCache+" Forcing memory check");
/*
发送消息重新checkMemory
*/
postCheckMemoryMsg(false, 0);
}
}
private final void clearCache() {
if (mClearCacheObserver == null) {
// Lazy instantiation
/*
创建一个CachePackageDataObserver对象,当PackageManagerService清理完空间时会回调该对象的
onRemoveCompleted方法
*/
mClearCacheObserver = new CachePackageDataObserver();
}
mClearingCache = true;
try {
if (localLOGV) Slog.i(TAG, "Clearing cache");
IPackageManager.Stub.asInterface(ServiceManager.getService("package")).
freeStorageAndNotify(mMemLowThreshold, mClearCacheObserver);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to get handle for PackageManger Exception: "+e);
mClearingCache = false;
mClearSucceeded = false;
}
}
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
//don't handle an invalid message
if (msg.what != DEVICE_MEMORY_WHAT) {
Slog.e(TAG, "Will not process invalid message");
return;
}
/*
收到后checkMemory
*/
checkMemory(msg.arg1 == _TRUE);
}
};
private void postCheckMemoryMsg(boolean clearCache, long delay) {
// Remove queued messages
mHandler.removeMessages(DEVICE_MEMORY_WHAT);
/*
发送消息给handler
*/
mHandler.sendMessageDelayed(mHandler.obtainMessage(DEVICE_MEMORY_WHAT,
clearCache ?_TRUE : _FALSE, 0),
delay);
}
class CachePackageDataObserver extends IPackageDataObserver.Stub {
public void onRemoveCompleted(String packageName, boolean succeeded) {
mClearSucceeded = succeeded;
mClearingCache = false;
if(localLOGV) Slog.i(TAG, " Clear succeeded:"+mClearSucceeded
+", mClearingCache:"+mClearingCache+" Forcing memory check");
/*
发送消息重新checkMemory
*/
postCheckMemoryMsg(false, 0);
}
}
private final void clearCache() {
if (mClearCacheObserver == null) {
// Lazy instantiation
/*
创建一个CachePackageDataObserver对象,当PackageManagerService清理完空间时会回调该对象的
onRemoveCompleted方法
*/
mClearCacheObserver = new CachePackageDataObserver();
}
mClearingCache = true;
try {
if (localLOGV) Slog.i(TAG, "Clearing cache");
IPackageManager.Stub.asInterface(ServiceManager.getService("package")).
freeStorageAndNotify(mMemLowThreshold, mClearCacheObserver);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to get handle for PackageManger Exception: "+e);
mClearingCache = false;
mClearSucceeded = false;
}
}
总结:
1. 构造方法:
1>. 构造方法中会获取3个分区的信息,包括,data,System,Cache;2>. 创建4个intent,分别用于通知内存不足,内存恢复正常,内存已满,内存不满;3>. 查询Settings数据获取最小,最大的内存限定(mMaxLowThreshold, mMemFullThreshold);4>. 检查内存
2. checkMemory:
1>. 如果正在清理缓存,do nothing;
2>. 重新计算3个分区的剩余空间大小;
3>. 如果内存不足,先尝试清除缓存,再重新计算分区大小,如果仍然不足,发送相应的广播;
4>. 如果内存已满,直接发送内存已满广播;
3. clearCache:
1>. 创建一个CachePackageDataObserver对象,当PackageManagerSevice清理完毕后回调onRemoveCompleted方法;
2>. onRemoveCompleted方法中调用postCheckMemoryMsg(false, 0),给handler发送消息,调用checkMemory重新计算3个分区的大小;