Android源码解析--DeviceStorageManagerService(DeviceStorageMonitorService)服务详解

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 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方法。

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》

你可能感兴趣的:(android源码分析)