Android 缓存获取与一键清理


发布日期 : 2023-12-04 14:04:23 UTC

访问量: 10 次浏览

获取应用程序缓存及一键清理:

1.什么是缓存呢?

在手机ROM里面的缓存就是每个程序的cache文件夹

2.获取缓存思路(参考手机设置页面)

通过 PakcageManager.getPakcageSizeInfo() 能得到程序的缓存,但是这个方法被隐藏了,而系统的 Setting 页面之所以能使用是因为它们的权限高,

我们要想使用就必须通过反射来得到,这里 getPackageSizeInfo() 方法的第二个参数是一个远程的 aidl 文件。

  • 所以必须要在本地的工程中新建一个包,名字为 android.content.pm
  • 拷贝 IPakcageStatsObserver.aidl 到该包中,导入后发现报错,是因为还要导入另外一个 aidl 文件 PackageStats.aidl

3.获取缓存大小

protected Void doInBackground(Void... params) {
try {
List<PackageInfo> infos = pm.getInstalledPackages(0);
//pm.getInstalledApplications(flags);
pb.setMax(infos.size());
int total = 0;

for (PackageInfo info : infos) {
String packname = info.packageName;
Method method = PackageManager.class.getDeclaredMethod(
"getPackageSizeInfo", new Class[] {
String.class,
IPackageStatsObserver.class });
method.invoke(pm, new Object[] { packname,
new MyObserver(packname) });
publishProgress("正在扫描:" + packname);
total++;
pb.setProgress(total);
Thread.sleep(80);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

private class MyObserver extends IPackageStatsObserver.Stub {
private String packname;
public MyObserver(String packname) {
this.packname = packname;
}
//回调方法,到得到状态之后就会调用该方法,我们可以通过PackageStats中的属性来得到缓存的大小
public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)
throws RemoteException {
long cache = pStats.cacheSize;
long code = pStats.codeSize;
long data = pStats.dataSize;
if (cache > 0) {
cacheInfo.put(packname, cache);
}
}
}

4.缓存清理

得到每个程序的缓存大小后,该怎么去清理程序的缓存呢?调用 PackageManager.deleteApplicationCacheFiles ,这个方法是隐藏的,我们通过反射来执行但是发现需要权限,

设置权限后还是提示需要权限,这是因为没有系统权限我们不能清理,设置页面之所以能够使用这个方法,因为是系统的API,所以我们只能是点击条目之后跳转到系统的设置页面,让通过设置页面来删除缓存.

5.一键清理

一键自动清理使用 freeStorageAndNotify 方法,该方法能够向系统申请释放多大的内存,系统会根据你申请的大小,尽可能的去是释放可以释放的大小。

public void cleanAll(View view) {
try {
Method[] ms = PackageManager.class.getDeclaredMethods();
for (Method m : ms) {
if ("freeStorageAndNotify".equals(m.getName())) {
m.invoke(pm, new Object[] { Long.MAX_VALUE,
new MyDataObersver() });
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

//这是一个aidl
private class MyDataObersver extends IPackageDataObserver.Stub {
public void onRemoveCompleted(String packageName, boolean succeeded)
throws RemoteException {
}
}