Skip to content

Latest commit

 

History

History
92 lines (82 loc) · 3.56 KB

获取应用程序缓存及一键清理.md

File metadata and controls

92 lines (82 loc) · 3.56 KB

获取应用程序缓存及一键清理

  1. 什么是缓存呢?
    在手机ROM里面的缓存就是每个程序的cache文件夹

  2. 获取缓存思路(参考手机设置页面)
    通过PakcageManager.getPakcageSizeInfo()能得到程序的缓存,但是这个方法被隐藏了,而系统的Setting页面之所以能使用是因为它们的权限高, 我们要想使用就必须通过反射来得到,这里getPackageSizeInfo()方法的第二个参数是一个远程的aidl文件。

    • 所以必须要在本地的工程中新建一个包,名字为android.content.pm
    • 拷贝IPakcageStatsObserver.aidl到该包中,导入后发现报错,是因为还要导入另外一个aidl文件PackageStats.aidl
  3. 获取缓存大小

    protected Void doInBackground(Void... params) {
    	try {
    		List<PackageInfo> infos = pm.getInstalledPackages(0);
    		//pm.getInstalledApplications(flags);
    		pb.setMax(infos.size());
    		int total = 0;
    		
    		for (PackageInfo info : infos) {
    			String packname = info.packageName;
    			Method method = PackageManager.class.getDeclaredMethod(
    					"getPackageSizeInfo", new Class[] {
    							String.class,
    							IPackageStatsObserver.class });
    			method.invoke(pm, new Object[] { packname,
    					new MyObserver(packname) });
    			publishProgress("正在扫描:" + packname);
    			total++;
    			pb.setProgress(total);
    			Thread.sleep(80);
    		}
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    	return null;
    }
    
    private class MyObserver extends IPackageStatsObserver.Stub {
        private String packname;
        public MyObserver(String packname) {
            this.packname = packname;
        }
        //回调方法,到得到状态之后就会调用该方法,我们可以通过PackageStats中的属性来得到缓存的大小
        public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)
                throws RemoteException {
            long cache = pStats.cacheSize;
            long code = pStats.codeSize;
            long data = pStats.dataSize;
            if (cache > 0) {
                cacheInfo.put(packname, cache);
            }
        }
    }
  4. 缓存清理 得到每个程序的缓存大小后,该怎么去清理程序的缓存呢?调用PackageManager.deleteApplicationCacheFiles,这个方法是隐藏的,我们通过反射来执行但是发现需要权限, 设置权限后还是提示需要权限,这是因为没有系统权限我们不能清理,设置页面之所以能够使用这个方法,因为是系统的API, 所以我们只能是点击条目之后跳转到系统的设置页面,让通过设置页面来删除缓存.

  5. 一键清理 一键自动清理使用freeStorageAndNotify方法,该方法能够向系统申请释放多大的内存,系统会根据你申请的大小,尽可能的去是释放可以释放的大小。

    public void cleanAll(View view) {
        try {
            Method[] ms = PackageManager.class.getDeclaredMethods();
            for (Method m : ms) {
                if ("freeStorageAndNotify".equals(m.getName())) {
                    m.invoke(pm, new Object[] { Long.MAX_VALUE,
                            new MyDataObersver() });
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }		
    }
    
    //这是一个aidl
    private class MyDataObersver extends IPackageDataObserver.Stub {
        public void onRemoveCompleted(String packageName, boolean succeeded)
                throws RemoteException {
        }
    }