利用IPackageManager接口进行缓存垃圾清理(释放存储)
利用IPackageManager接口进行缓存垃圾清理
- 获取IPackageManager
- getPackageSizeInfo方法介绍
- freeStorageAndNotify方法释放存储空间
- clearApplicationUserData方法清除用户数据
- 删除cache文件目录来清除缓存
- PMS源码中LI、LIF、LP(LPw、LPr)的含义
- 结语
获取IPackageManager
通过Context.getPackageManager
方法可得到PackageManager
,通过PackageManager
可实现一些应用处理。
public PackageManager getPackageManager(){if(mPackageManager !=null){return mPackageManager;}IPackageManager pm = ActivityThread.getPackageManager();if(pm != null){return (mPackageManager = new ApplicationPackageManager(this, pm));}return null;
}
PackageManager
的实质为获取IPackageManager
,即PackageManagerService
的客户端代理接口,PackageManager
为抽象类,实际实现为ApplicationPackageManager
,为包级类,无法直接访问。
IPackageManager
获取的两种方式如下:
IPackageManager pm = ActivityThread.getPackageManager()
IPackageManager pm = AppGlobals.getPackageManager()
实际都是通过ActivityThread.getPackageManager()
。
getPackageSizeInfo方法介绍
getPackageSizeInfo
为获取应用缓存大小,方法参数如下:
public void getPackageSizeInfo(String packageName, int userHandle, IPackageStatsObserver observer)
检索包的大小信息。由于这可能需要一点时间,结果将被发送回给定的观察者。需要android.Manifest.permission.GET_PACKAGE_SIZE
权限。 参数packageName 要获取其大小信息的包的名称 。参数 userHandle 应获取其大小信息的用户。 参数observer 操作完成时收到通知的观察者回调。使用 PackageStats
对象(包含包的代码、数据和缓存大小)和表示操作状态的布尔值调用观察者的回调,观察者为空时表示不需要回调。 此方法android弃用, 使用StorageStatsManager
代替,StorageStatsManager
用法详见博客:android利用StorageStatsManager获取应用程序的存储信息。
PackageStatsObserver packageStatsObserver = new PackageStatsObserver();try {iPackageManager.getPackageSizeInfo(packageName, UserHandle.myUserId(), packageStatsObserver);} catch (RemoteException e) {e.printStackTrace();}private static class PackageStatsObserver extends IPackageStatsObserver.Stub {@Overridepublic void onGetStatsCompleted(PackageStats packageStats, boolean b) throws RemoteException {String packageName = packageStats.packageNamelong cacheSize = packageStats.cacheSizeString cacheStr = Formatter.formatShortFileSize(mContext, packageStats.cacheSize)}}
可调用Formatter.formatShortFileSize(mContext, cacheSize)
格式化文件大小。
freeStorageAndNotify方法释放存储空间
PackageDataObserver packageDataObserver = new PackageDataObserver();try {iPackageManager.clearApplicationUserData(packageName, packageDataObserver, UserHandle.myUserId());StatFs stat = new StatFs(Environment.getDataDirectory().getAbsolutePath());iPackageManager.freeStorageAndNotify(volumeUuid, (long) stat.getBlockCount() * (long) stat.getBlockSize(), packageDataObserver);iPackageManager.deleteApplicationCacheFiles(packageName, packageDataObserver);} catch (RemoteException e) {e.printStackTrace();}private static class PackageDataObserver extends IPackageDataObserver.Stub {@Overridepublic void onRemoveCompleted(String packageName, boolean result) throws RemoteException {}}
freeStorageAndNotify
方法通过删除所有应用程序中按 LRU 排序的缓存文件列表来释放存储空间。如果设备上当前可用的空闲存储空间大于或等于请求的空闲存储空间,则不会清除缓存文件。如果设备上当前可用的存储空间小于请求的可用存储空间,则删除所有应用程序中的部分或全部缓存文件(基于上次访问时间),以将设备上的可用存储空间增加到请求的值。无法保证从所有应用程序中清除所有缓存文件将清除足够的存储空间以实现所需的值。freeStorageSize 系统要释放的存储字节数。说如果freeStorageSize是XX,当前空闲存储是YY,如果XX小于YY,直接返回。如果可能,则释放 XX-YY 字节数。 观察者回调用于通知操作何时完成。
方法参数:
public void freeStorageAndNotify(@Nullable String volumeUuid, long freeStorageSize,@Nullable IPackageDataObserver observer)
最终通过frameworks/native/cmds/installd/binder/android/os/IInstalld.aidl
的AIDL接口调用到frameworks/native/cmds/installd/InstalldNativeService.cpp
的Native服务进行存储释放。
Installer
方法:
InstalldNativeService.cpp
的方法:
clearApplicationUserData方法清除用户数据
通过ActivityManager
清除用户数据方式如下:
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);boolean res = am.clearApplicationUserData(packageName, packageDataObserver);
其过程AMS与PMS通信调用clearApplicationUserData
清除用户数据。
利用IPackageManager
清除用户数据的方式如下:
try {iPackageManager.clearApplicationUserData(packageName, packageDataObserver, UserHandle.myUserId());} catch (RemoteException e) {e.printStackTrace();}
clearApplicationUserData
清除用户数据的过程不仅清除保存的用户数据,同时也清除了缓存数据cacheFiles即deleteApplicationCacheFiles
,如果单独清除缓存可调用如下方法:
iPackageManager.deleteApplicationCacheFiles(packageName, packageDataObserver);
deleteApplicationCacheFiles
方法清除应用缓存,即清除cache目录。
clearApplicationUserData
最终在PMS访问Installer
与InstalldNativeService
的Native服务进行数据清理。
Installer
方法:
InstalldNativeService.cpp
的方法:
删除cache文件目录来清除缓存
除了通过上述PackageManager.deleteApplicationCacheFiles(packageName, packageDataObserver)
还有另一种方法,通过删除cache文件目录:
public void clearALLCache() {List<PackageInfo> packList = mPackageManager.getInstalledPackages(PackageManager.DELETE_CHATTY);for (int i=0; i < packList.size(); i++){PackageInfo packInfo = packList.get(i);//非系统应用if ((packInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {try {Context context = getApplicationContext().createPackageContext(packInfo.packageName,Context.CONTEXT_IGNORE_SECURITY);deleteCache(context);} catch (Exception e) {e.printStackTrace();}}}}public static void deleteCache(Context context) {try {File dir = context.getCacheDir();deleteDir(dir);} catch (Exception e) {e.printStackTrace();}}public static boolean deleteDir(File dir) {if (dir != null && dir.isDirectory()) {String[] children = dir.list();for (String child : children) {boolean success = deleteDir(new File(dir, child));if (!success) {return false;}}return dir.delete();} else if(dir!= null && dir.isFile()) {return dir.delete();} else {return false;}}
通过得到安装应用列表,遍历得到应用package的Context
,通过Context
得到缓存目录,遍历文件目录进行删除。
PMS源码中LI、LIF、LP(LPw、LPr)的含义
PackageManagerService
内部使用的两个锁来进行应用数据操作。用LI、LIF、LP(LPw、LPr)后缀名来标志加锁处理,因为其中开头字母L指的是Lock
锁,而后的字母I和P指的是两个锁,I表示mInstallLock
同步锁(安装锁),P表示mPackages
同步锁(包锁)。LPw、LPr中的w表示writing,r表示reading。LIF中的F表示Freeze
。
mPackages
同步锁,是指操作mPackages
时,用对mPackages加锁保护起来。mPackages
同步锁用来保护内存中已经解析的包信息和其他相关状态。mPackages
同步锁是细粒度的锁,只能短时间持有这个锁,因为争抢mPackages
锁的请求很多,短时间持有mPackages
锁,可以让其他请求等待的时间短些。
mInstallLock
同步锁,是指安装App的时候,对安装的处理要用mInstaller
加锁保护起来。同时用来保护所有对installd
的访问。installd
通常包含对应用数据的繁重操作。
由于installd
是单线程的,并且installd
的操作通常很慢,所以在已经持有mPackages
同步锁的时候,千万不要再请求mInstallLock同步锁。反之,在已经持有mInstallLock
同步锁的时候,可以去请求mPackages
同步锁。
具体参考PackageManagerService中的方法名中的LI、LIF、LPw、LPr的含义
结语
以上为利用IPackageManager
接口进行缓存垃圾清理,此为系统应用调用的接口,在使用过程中需考虑特殊应用是否需要清理以免删除重要数据!!!
利用IPackageManager接口进行缓存垃圾清理(释放存储)相关推荐
- 苹果手机怎么清理缓存_【优化】苹果清理缓存垃圾终极方案丨还你干净手机
手机使用时间长了垃圾越来越多怎么办?手机没越狱能清理垃圾吗?越狱手机用时间长了垃圾多了变慢了怎么办?等等问题,今天一站式帮你解决! 需要工具: 越狱的手机一部: 手机端安装 iCleaner Pro ...
- win10系统中如何不用360安全卫士等软件仍能实现清理垃圾,释放内存和安全防护的基本功能
对于很多电脑小白来说,如果没有安全卫士或者电脑管家这样的软件协助,可能根本不知道如何管理自己的电脑.但其实装了这些所谓的管家软件,电脑运行速度不仅不能变快,反而会因为这些软件的运行而减缓.我们用安全卫 ...
- 软件测试面试题:接口产生的垃圾数据如何清理
接口产生的垃圾数据如何清理 需用python连数据库了,做增删改查的操作测试用例前置操作,setUp做数据准备后置操作,tearDown做数据清理 个人简介 我是一名测试兼开发工程师,目前25K,目前 ...
- iphone储存空间系统怎么清理_教你快速清理 iPhone 系统缓存垃圾,拒绝卡顿!
「 改变能改变的一切,接受不能改变的一切!」 ▼ "iPhone存储空间"里的系统为何占用了几十G的甚至上百G的内存,如何清理?当我们使用 iPhone 一段时间之后,系统或应用中 ...
- android 垃圾清理 文件清理
欢迎转载,转载请注明:http://blog.csdn.net/zhgxhuaa 说明 在总篇中提到过垃圾清理,本篇将着重介绍针对缓存.卸载残留.无用数据等"静态内容"的清理,有关 ...
- 手机管理应用研究【3】—— 垃圾清理篇
欢迎转载,转载请注明:http://blog.csdn.net/zhgxhuaa 说明 在总篇中提到过垃圾清理,本篇将着重介绍针对缓存.卸载残留.无用数据等"静态内容"的清理,有关 ...
- Mac重启清理缓存会怎么样 mac清理缓存怎么清理
众所周知,Mac电脑有着流畅的操作系统,因此,很多用户都会选择使用Mac电脑办公.随着日常使用,系统缓存数据越来越大,某些Mac电脑(尤其是小内存版本的Mac电脑)可能会出现"系统" ...
- 网站服务器垃圾清理,服务器安全狗垃圾清理功能操作教程
垃圾清理功能,大家都不陌生.服务器安全狗的垃圾清理功能通过对包括系统垃圾文件和注册表垃圾的清理,帮助用户提高系统运行速度与效率. 下面我们一起来详细了解下垃圾清理功能: 垃圾清理分为文件清理与注册表清 ...
- JVM垃圾清理机制详解 ✨ 每日积累
JVM垃圾清理机制详解 jvm内存结构中有一块地方叫做堆内存,里面存放着我们应用创建的对象,但是我们堆内存有限,对象在运行的时候持续创建,jvm有垃圾清理机制来清理对象确保堆内存的可用空间. 清理流程 ...
最新文章
- 程序员提交代码的 emoji 指南——原来表情文字不能乱用
- 《深入理解 Java 内存模型》读书笔记(下)(干货,万字长文)
- java接口和实例_java – 接口和实例化
- tomcat(13)Host和Engine容器
- recycleview 使用详解,添加头部尾部,混合item,侧滑菜单,跳转到指定位置,实现九宫格布局
- 安卓--selector简单使用
- 使用nagios监控oracle
- 理解和使用SQL Server中的并行
- 让Netty入门变得简单
- python退出函数_【转】python 退出程序的方式
- dubbo kryo序列化_Java后端精选技术:序列化框架的选型和比对
- 子寅:不会“怼”产品经理,干不了程序员,更干不好脱口秀
- oracle卸数的perl脚本,卸载cpan安装的所有perl模块
- PCB电路板如何设计散热
- vivado使用方法(初级)
- 没有技巧的运营公众号,大概率是用爱发电吧!
- JVM--GC相关记录
- ALTERA CPLD离线烧写方案设计(MCU模拟JTAG)
- android手机查看设备ID,deviceID
- linux运行php文件
热门文章
- 获取12306各个站点的简称
- 【易语言】易语言制作-bt天堂ok资源采集器(网络爬虫)
- supermap获取许可
- MySQL安装教程(超详细教程)
- PS下载第三方系统附件
- django 微信网页授权登陆实战
- 2018,你还差一场深度纵横的以太坊技术盛宴
- 一种解决 【Jupyter Notebook 由于超时无法打开kernel】与【Pycharm 卡在启动界面】的方法
- 计算机app无法删除,苹果桌面软件无法删除怎么办_苹果电脑桌面软件删除不了如何处理-win7之家...
- 怎样写一个通用的JavaScript效果库!