今天在制作仿小米安全中心时,遇到一个棘手的功能,清除缓存,很简单啊,心头一想,马上就想到了直接删除其他应用的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); 

是不是简单很多呢,就这样就完成了,但就少了很多扩展性,看你选那一样咯

   
   


更多相关文章

  1. Android(安卓)Studio 快捷键
  2. Android(安卓)led灯实现大致流程
  3. Android[高级教程] 设计模式之七 单例模式
  4. Android(安卓)Jni代码示例讲解
  5. android 中 AppWidget 的 ListView 的实现
  6. android的surfaceview的用法
  7. Android(安卓)AIDL 双向调用的使用及相关原理
  8. Android面试知识点总结-Android篇
  9. 通用(任何android机型)Root教程(完整版!附砖机自救方法)

随机推荐

  1. Android动态换肤(一、应用内置多套皮肤)
  2. Android实用工具类-GrallyAndPhotoUtils
  3. Android异常捕获篇(下)---retrofit实现文件
  4. Android(安卓)Studio精彩案例(三)《模仿
  5. Android实用视图动画及工具系列之三:表情
  6. 摩托罗拉咬定Android不放松2011-01-17 14
  7. 轻听变色之谜-如何改变Android应用的主题
  8. 【设计模式与Android】迭代器模式——容
  9. Android(安卓)App驱动Arduino通过蓝牙控
  10. android中常见的内存溢出和解决办法