您的位置:首页 > 移动开发

安卓怎样获得所有的APP缓存使用getPackageSizeInfo

2016-05-13 20:59 393 查看
今天写了一个程序来获得所有程序的缓存。在写这个程序的过程中遇到了很多的困难,并且一一解决了,现在我来给大家分享一下,如何获得安卓内所有程序的缓存信息:

首先,需要获得所有已经安装的程序的基本信息通过packageManager来拿到

List<PackageInfo> installedPackages = manager.getInstalledPackages(0);
拿到所有的程序基本信息后,通过for循环来拿到程序的包名,然后通过查询android源码,在setting里面找到了拿到缓存大小的源码,通过packageManager的getPackageSizeInfo方法来拿到。

public abstract void getPackageSizeInfo(String packageName, int userHandle,
IPackageStatsObserver observer);
然而这个方法是隐藏的,我们通过反射来拿到这个方法

Class<?> loadClass = getClassLoader().loadClass("android.content.pm.PackageManager");
Method 	method = loadClass.getDeclaredMethod("getPackageSizeInfo", String.class,int.class,IPackageStatsObserver.class);


在这个方法中,userHandle是一个难点,在android 4.2之后,这个userHandle才出现。handle就是句柄的意思,这个含义在C语言中经常出现。在这里,我们通过句柄来获取这个具体的APP,在这里,我们在方法中设置 Progress.getUserId() / 10000;来进行设置。

为什么会/100000呢,因为在安卓内部,默认能够设置的APP数量就是100000,通过这个计算来拿到handle.

在getPackageSizeInfo 这个方法中,我们还需要设置IPackageStatsObserver 这个类。下面我们通过继承来实现这个类

private class MyIPackageStatsObserver extends IPackageStatsObserver.Stub{

private PackageInfo packageInfo;

public  MyIPackageStatsObserver(PackageInfo packageInfo){
this.packageInfo = packageInfo;

}

@Override
public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)
throws RemoteException {
// TODO Auto-generated method stub
//获取到当前手机应用缓存大小
long cacheSize = pStats.cacheSize;
if(cacheSize != 0){
System.out.println("当前应用的名字"+packageInfo.applicationInfo.loadLabel(manager));
CacheInfo cacheInfo = new CacheInfo();
cacheInfo.icon = packageInfo.applicationInfo.loadIcon(manager);
cacheInfo.cacheSize  = cacheSize;
cacheInfo.appName = packageInfo.applicationInfo.loadLabel(manager).toString();
cacheInfos.add(cacheInfo);
System.out.println("获得缓存数据是对的,拿到了数据"+cacheSize);

}
adapter.notifyDataSetChanged();

}

}

static class CacheInfo{
Drawable icon;
long cacheSize;
String appName;
}


在实现的过程中,我通过在子线程里面来加载这些数据,发现,这个实现的类去实现需要延长一段时间。为了详细的讲述,我先上代码来看看我是怎样来实现的

private  void initUI(){

manager = getPackageManager();

cacheInfos = new ArrayList<CacheInfo>();

adapter = new MyAdapter();
listView = (ListView) findViewById(R.id.list_view);

new Thread(){
public void run() {

//数据加载完成后,开始初始化adapter

List<PackageInfo> installedPackages = manager.getInstalledPackages(0);
//				for (PackageInfo packageInfo : installedPackages) {
//					getCacheSize(packageInfo);
//				}

int count=0;
while(count != installedPackages.size()){
getCacheSize(installedPackages.get(count));

count++;
System.out.println(count + "安装程序数量");
}

handler.sendEmptyMessage(0);
};
}.start();

}


大家可以看到,我是在数据加载完成之后,发送一个消息来刷新UI,使listView来显示数据,可是我发现,
getCacheSize这个会延迟,也就是在发送消息之后,他才进行数据的加载,这个好像是因为AIDL接口的调用而产生的延时,为了解决这个延时,我在这个接口的实现函数中添加了adapter.notifyDataSetChanged();<span style="white-space:pre">	</span>


因为onGetStatsCompleted这个函数是一个回调函数,在主线程中运行,所以就完美的解决了这个问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: