zoukankan      html  css  js  c++  java
  • Android开发——获取应用数据/缓存大小并清理缓存

    1. 获取应用数据/缓存大小

    其中pm为实例化的PackageManager,因为需要遍历所有的已安装的应用。因此需要开启子线程进行处理。

    还有需要注意的是,在Android4.2之前getPackageSizeInfo方法参数是没有第二个int类型的参数的,贴出来的代码适合4.2以后的版本,在反射获取方法时,增加了userHandle的参数信息。至于增加的参数userHandle的解释是:The user whose size information should be retrieved。我们是通过系统类的UserHandle.myUserId()获取。

    还有需要注意的是,因为调用了远程服务,需要在自己的工程里引入两个aidl文件,分别是IPackageStatsObserver.aidl以及PackageStats.aidl,放在新建的android.content.pm包下。

        private void scanCache() {
            pm = getPackageManager();
            new Thread(){
                @Override
                public void run() {
                    List<PackageInfo> installedPackages = pm.getInstalledPackages(0);
                    for( PackageInfo info : installedPackages){
                        try {
                            Method myUserId = UserHandle.class.getDeclaredMethod("myUserId");
                            int userID = (Integer) myUserId.invoke(pm,null);
                            Method getPackageSizeInfo = pm.getClass().getDeclaredMethod("getPackageSizeInfo", String.class,
                                    int.class, IPackageStatsObserver.class);
                            getPackageSizeInfo.invoke(pm, info.packageName, userID, new MyDataObserver());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                           //扫描结束后的UI操作
                        }
                    });
                }
            }.start();
        }
    
        private  class MyDataObserver extends IPackageStatsObserver.Stub{
            @Override
            public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)
                    throws RemoteException {
                final long cache = pStats.cacheSize; //应用缓存的大小
                long code = pStats.codeSize;
                long data = pStats.dataSize;//这里便可以拿到应用数据的大小
                String packageName = pStats.packageName;
                ApplicationInfo appinfo = null;
                try {
                    appinfo = pm.getApplicationInfo(packageName,0);
                    final ApplicationInfo finalAppinfo = appinfo;
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                                //拿到cache,处理UI
                                }
                            }
                        });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

    2. 清理缓存

    据我所知,是不可以在应用里根据包名只清理一个应用的缓存的,除非是系统级别的应用才有DELETE_CACHE_FILES权限。但是可以通过PackageManager的freeStorageAndNotify方法,声称需要一个比较大的内存空间,从而达到清理所有应用的缓存文件的目的。

    同样需要注意添加IPackageDataObserver.aidl接口声明,包位置依旧是android.content.pm

        private void deleteAllCache() {
            pm = getPackageManager();
            Method[] methods = PackageManager.class.getMethods();
            for(Method method : methods){
                if( "freeStorageAndNotify".equals(method.getName())  ) {
                    try {
                        method.invoke(pm,Long.MAX_VALUE,new MyPackageDataObserver());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return;
                }
            }
        }
    同时在清理完成时,会回调onRemoveCompleted方法。比较适合做清理完毕后的UI逻辑。

    本例是弹出一个对话框提示用户清理完毕。

        private  class MyPackageDataObserver extends IPackageDataObserver.Stub{
            @Override
            public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            AlertDialog.Builder builder = new AlertDialog.Builder(CleanCacheActivity.this);
                            builder.setMessage("恭喜,已清理所有垃圾");
                            builder.setTitle("提示");
                            builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.dismiss();
                                    finish();
                                }
                            });
                            builder.create().show();
                        }
                    });
            }
        }


  • 相关阅读:
    《30天自制操作系统》06_day_学习笔记
    《30天自制操作系统》05_day_学习笔记
    《30天自制操作系统》04_day_学习笔记
    ugui Event.current.mousePosition获取的坐标原点在左上角
    场景中GameObject无法用代码隐藏问题(setActive为false)
    让camera实现类似cs第一人称视角旋转和位移
    itunesconnect如何提交被决绝过了的相同版本号
    mac下安装libpng环境
    golang实现模拟键盘按键
    cocos2d3.x在android下屏蔽多点触控
  • 原文地址:https://www.cnblogs.com/qitian1/p/6461609.html
Copyright © 2011-2022 走看看