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

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

首先,需要获得所有已经安装的程序的基本信息通过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这个函数是一个回调函数,在主线程中运行,所以就完美的解决了这个问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值