今天在制作仿小米安全中心时,遇到一个棘手的功能,清除缓存,很简单啊,心头一想,马上就想到了直接删除其他应用的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();
}
}
public abstract void getPackageSizeInfo(String packageName,
IPackageStatsObserver observer);
//见两个参数,包名和远程调用,在这里有的同学没学过远程通讯吧?贴下代码:
Class extends PackageManager> class1=mManager.getClass();//packagemanager mManager
Method method = null;
try {
method = class1.getMethod("getPackageSizeInfo",
String.class,IPackageStatsObserver.class);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
method.invoke(mManager,ai.packageName, new ClearPackageOvserver(ai));
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
三个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(String packageName,
*IPackageStatsObserver observer); 当调用了这个方法后,就会回调里面的
*onGetStatsCompleted方法并在pStats存储了相关的信息
**/
private class MyPackageOvserver extends IPackageStatsObserver.Stub{
@Override
public 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() {
@Override
public 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);
是不是简单很多呢,就这样就完成了,但就少了很多扩展性,看你选那一样咯