安卓怎样获得所有的APP缓存使用getPackageSizeInfo
2016-05-13 20:59
393 查看
今天写了一个程序来获得所有程序的缓存。在写这个程序的过程中遇到了很多的困难,并且一一解决了,现在我来给大家分享一下,如何获得安卓内所有程序的缓存信息:
首先,需要获得所有已经安装的程序的基本信息通过packageManager来拿到
在这个方法中,userHandle是一个难点,在android 4.2之后,这个userHandle才出现。handle就是句柄的意思,这个含义在C语言中经常出现。在这里,我们通过句柄来获取这个具体的APP,在这里,我们在方法中设置 Progress.getUserId() / 10000;来进行设置。
为什么会/100000呢,因为在安卓内部,默认能够设置的APP数量就是100000,通过这个计算来拿到handle.
在getPackageSizeInfo 这个方法中,我们还需要设置IPackageStatsObserver 这个类。下面我们通过继承来实现这个类
在实现的过程中,我通过在子线程里面来加载这些数据,发现,这个实现的类去实现需要延长一段时间。为了详细的讲述,我先上代码来看看我是怎样来实现的
大家可以看到,我是在数据加载完成之后,发送一个消息来刷新UI,使listView来显示数据,可是我发现,
因为onGetStatsCompleted这个函数是一个回调函数,在主线程中运行,所以就完美的解决了这个问题。
首先,需要获得所有已经安装的程序的基本信息通过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这个函数是一个回调函数,在主线程中运行,所以就完美的解决了这个问题。
相关文章推荐
- Android填坑系列:Android JSONObject 中对key-value为null的特殊处理
- Android最新flash播放器----支持安卓5.0+系统。
- iOS开发之category动态添加属性的方法------关联
- Android 推送和统计最优轮循(心跳策略)探究实践
- android studio打包apk 百度地图不显示的问题
- Android 最优轮循(心跳策略)探究实践
- hdu2830 Matrix Swapping II(DP)
- Android内核开发:在源码树中添加新的app应用
- Android 学习笔记之七 Application类
- 阅读郭林《第一行代码》的笔记——第1章 开始启程,你的第一行Android代码
- Android内核开发:从源码树中删除出厂的app应用
- Appium Server 源码分析 (二) - main 方法
- JAVA 学到什么水平就可以转战 Android 了?
- 去掉tabbar上方的黑线
- Android内核开发:浅析APK的安装过程
- Android内核开发:系统启动速度优化
- Android内核开发:学会分析系统的启动log
- 学习Android studio 个人总结小经验
- Android之应用市场评分
- Android:onClick 底层属性调用