Android清除所有应用的缓存(包括系统应用)的两种实现方法
16lz
2021-01-24
今天在制作仿小米安全中心时,遇到一个棘手的功能,清除缓存,很简单啊,心头一想,马上就想到了直接删除其他应用的cache dir.
public static long getSize(File file) throws Exception {/***获取本包有没有缓存,没有就跳过*@param file 传入的cache address,sdcard里为"/mnt/sdcard/packageName包名/cache/" 内部存储:"/data/data/包名/cache/" **///删除指定包名的cache文件夹static boolean delete(File dir) { if (dir != null && dir.isDirectory()) { String[] children = dir.list(); int size = 0; if (children != null) { size = children.length; for (int i = 0; i < size; i++) { boolean success = deleteDir(new File(dir, children[i])); if (!success) { return false; } } } } if (dir == null) { return true; } else { return dir.delete(); } }
然而, 这个做法是错误的 .逻辑是没问题的,就是找出所有应用的资料存储位置,然后删除cache文件夹里的内容,但经实践,这是不能执行的,要能这么轻松就能删除,那么很多应用都可以随意地删除其他应用的文件.实际上,是需要绕一些弯的,android是不允许擅自删除其他应用的文件的,不希望我们去调用它,最后我发现了:一个private的方法隐藏在源码里:那就是 PackageManager里的方法
public abstract void getPackageSizeInfo(String packageName, IPackageStatsObserver observer);//见两个参数,包名和远程调用,在这里有的同学没学过远程通讯吧?贴下代码:Class<? extends PackageManager> class1=mManager.getClass();//packagemanager mManagerMethod method = null;try {method = class1.getMethod("getPackageSizeInfo",String.class,IPackageStatsObserver.class);} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();}try {method.invoke(mManager,ai.packageName, new ClearPackageOvserver(ai));} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();}
首先创建一个包,名称是android.content.pm,必须是这个名字,IPackageStatsObserver是不关联代码的,在源码里找不到的,必须手动写
三个aidl的实现是:
package android.content.pm;/**IPackageDataObserver aidl
* * API for package data change related callbacks from the Package Manager. * Some usage scenarios include deletion of cache directory, generate * statistics related to code, data, cache usage(TODO) * {@hide} */oneway interface IPackageDataObserver { void onRemoveCompleted(in String packageName, boolean succeeded);}
package android.content.pm;import android.content.pm.PackageStats;/**IPackageStatsObserver aidl * API for package data change related callbacks from the Package Manager. * Some usage scenarios include deletion of cache directory, generate * statistics related to code, data, cache usage(TODO) * {@hide} */oneway interface IPackageStatsObserver { void onGetStatsCompleted(in PackageStats pStats, boolean succeeded);}
package android.content.pm;/**PackageStats
*/
parcelable PackageStats; getPackageSizeInfo的远程实现是:
/****getPackageSizeInfo(String packageName,*IPackageStatsObserver observer); 当调用了这个方法后,就会回调里面的*onGetStatsCompleted方法并在pStats存储了相关的信息**/private class MyPackageOvserver extends IPackageStatsObserver.Stub{@Overridepublic void onGetStatsCompleted(PackageStats pStats, boolean succeeded)throws RemoteException {Log.i(pStats.packageName, pStats.cacheSize+" "+pStats.codeSize+" "+pStats.dataSize+" "+pStats.externalCacheSize);if(pStats.cacheSize!=0){//有缓存}}}//上面是获得了缓存的相关信息,那么下面就进行清理缓存的操作try {Class clazz = mManager.getClass();Method method = clazz.getMethod("freeStorageAndNotify", long.class,IPackageDataObserver.class);method.invoke(mManager, Long.MAX_VALUE,dataObserver);} catch (Exception e) {e.printStackTrace();}//远程调用IpackageDataObserver的实现是:private IPackageDataObserver observer = new IPackageDataObserver.Stub() {@Overridepublic void onRemoveCompleted(String packageName, boolean succeeded)throws RemoteException {//删除完后的回调}};
这个是第一种方法,下面进行第二种方法:
Context context = createPackageContext("你要获取的应用包名", Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY); //Class classz = context.getClassLoader().loadClass("com.example.MainActivity"); //Object object = classz.newInstance(); File file1=clazz.getMethod("getCacheDir").invoke(object); File file2=clazz.getMethod("getExternalCacheDir").invoke(object);
是不是简单很多呢,就这样就完成了,但就少了很多扩展性,看你选那一样咯
更多相关文章
- Android(安卓)Studio 快捷键
- Android(安卓)led灯实现大致流程
- Android[高级教程] 设计模式之七 单例模式
- Android(安卓)Jni代码示例讲解
- android 中 AppWidget 的 ListView 的实现
- android的surfaceview的用法
- Android(安卓)AIDL 双向调用的使用及相关原理
- Android面试知识点总结-Android篇
- 通用(任何android机型)Root教程(完整版!附砖机自救方法)