Android11 app存储大小显示源码解析

问题背景:

Android11版本下,设置-应用和通知-所有应用信息-单个app应用信息详情,应用大小的显示,具体获取应用大小的最终来源:

首先单个app应用信息详情页面显示的地方,在/packages/apps/Settings/src/com/android/settings/applications/AppStorageSettings.java 类中,在onLoadFinished()方法中通过了Loader加载了应用存储结构:AppStorageStats

而加载器Loader是在onCreateLoader()方法中创建的,通过实例化FetchPackageStorageAsyncLoader类来创建的。注意,实例化FetchPackageStorageAsyncLoader时有传入一个参数ApplicatioiInfo  mInfo,这个是通过应用包名获取ApplicationInfo实例,后续获取应用大小都与这个参数相关联。在FetchPackageStorageAsyncLoader.javaloadInBackground()方法中获取到的AppStorageStats对象

下面追踪到

packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java中的getStatsForPackage()方法中:


继续到frameworks/base/core/java/android/app/usage/StorageStatsManager.java中的queryStatsForPackage()方法中:


再继续到/frameworks/base/services/usage/java/com/android/server/usage/StorageStatsService.java 中的queryStatsForPackage()方法

在该方法中,如果应用是系统应用的话,则应用大小不计算ApplicationInfo中getCodePath()大小,即apk包存放大小;最终调用Installer.java中的getAppSize()方法,将大小存储到PackageStats对象中,最终在translate()方法中,应用大小 = PackageStats.codeSize + PackageStats.externalCodeSize

frameworks/base/services/core/java/com/android/server/pm/Installer.java 中getAppSize()方法

这里的mInstalld是通过binder通信机制,与installd服务建立通信,对installd服务的实例化:

installd服务所在的类就是frameworks/native/cmds/installd/InstalldNativeService.cpp。InstalldNativeService.cpp中的getAppSize()方法最终调用了collectQuotaStats()方法,走的配额统计获取appSize,更快地获得存储统计信息。在早期版本的Android 中,系统会遍历特定应用拥有的所有文件以测量磁盘使用情况。此手动测量过程可能需要几分钟的计算时间,然后才能在“设置”中向用户显示结果。

此外,清除缓存数据文件的内部算法仅查看所有应用的修改时间。这使得恶意应用可以通过将修改时间设置在遥远的未来以使其不当地拥有高于其他应用的优先级,从而降低整体用户体验。

为了提升这些体验,Android 8.0 会询问是否利用 ext4 文件系统的“配额”支持来几乎即时地返回磁盘使用情况统计信息。此配额功能还可以防止任何单个应用使用超过 90% 的磁盘空间或 50% 的索引节点,从而提高系统的稳定性。

再继续往下看看

再继续看看GetOccupiedSpaceForGid()方法,该方法在frameworks/native/cmds/installd/QuotaUtils.cpp

在看看FindQuotaDeviceForUid()方法

mQuotaReverseMounts这个是怎么赋值的?它是通过frameworks/native/cmds/installd/QuotaUtils.cpp中的InvalidateQuotaMounts()方法赋值的,而调用InvalidateQuotaMounts()地方就有Installer.java中通过binder机制链接InstallNativeService的代码中就体现出来了,在frameworks/base/services/core/java/com/android/server/pm/Installer.java 中

frameworks/native/cmds/installd/InstalldNativeService.cpp中invalidateMounts()方法

这里就调用了之前说的给mQuotaReverseMounts赋值的方法了。

我们再来看看这个给mQuotaReverseMounts赋值的方法InvalidateQuotaMounts()

这里就是将/dev/block/下的分区挂载到文件目录,例如:Found quota mount /dev/block/dm-10 at /data

而挂载的分区支持配额功能,故后续只要installd启用配额功能就能快速获取到应用存储统计信息,从而快速获取到单个app应用显示大小

你可能感兴趣的:(Android11 app存储大小显示源码解析)