您的位置:首页 > 编程语言 > Java开发

利用反射函数实现一键清除缓存,并获取清除的缓存数目。调用反射函数类出错java.lang.NoSuchMethodException: getPackageSizeInfo.

2014-07-25 13:58 1036 查看
在开发一键清缓存的功能时,缓存清除成功,当使用反射调用IPackageStatsObserver.class 这个类时,系统提示错误:java.lang.NoSuchMethodException: getPackageSizeInfo [class java.lang.String, interface android.content.pm.IPackageStatsObserver]W/System.err(12295):    at java.lang.Class.getConstructorOrMethod(Class.java:460)W/System.err(12295):    at java.lang.Class.getDeclaredMethod(Class.java:685)字面意思很简单没有找到该方法,但是查看我的源码,包导入正常,只能查看自己的代码,找到出错的位置/*** 取得指定包名的程序的缓存大小*/private void queryPkgCacheSize(String pkgName) throws Exception {if (!TextUtils.isEmpty(pkgName)) {// pkgName不能为空// 使用放射机制得到PackageManager类的隐藏函数getPackageSizeInfoif (mPackageManager == null) {mPackageManager = getContext().getPackageManager();// 得到被反射调用函数所在的类对象}try {// the requested method's name.String strGetPackageSizeInfo = "getPackageSizeInfo";// 通过反射机制获得该隐藏函数Method getPackageSizeInfo = mPackageManager.getClass().getDeclaredMethod(strGetPackageSizeInfo, String.class,// getPackageSizeInfo方法的参数类型IPackageStatsObserver.class);// getPackageSizeInfo方法的参数类型// 调用该函数,并且给其分配参数 ,待调用流程完成后会回调PkgSizeObserver类的函数getPackageSizeInfo.invoke(mPackageManager,// 方法所在的类pkgName, mStatsObserver);// 方法使用的参数} catch (Exception ex) {Log.wtf("tag", "queryPkgSize()-->NoSuchMethodException");ex.printStackTrace();throw ex; // 抛出异常}}}是
.getDeclaredMethod()
方法报错的。经查看,我调用反射类IPackageDataObserver.class;却没有报错,调用方法为/*** 执行清除缓存操作*/private void clearCache() {totalCacheSize = 0l;// 初始化queryToatalCache();// 给cacheSize赋值try {if (mPackageManager == null) {mPackageManager = getContext().getPackageManager();// 得到被反射调用函数所在的类对象}String methodName = "freeStorageAndNotify";// 想通过反射机制调用的方法名Class<?> parameterType1 = Long.TYPE;// 被反射的方法的第一个参数的类型Class<?> parameterType2 = IPackageDataObserver.class;// 被反射的方法的第二个参数的类型Method freeStorageAndNotify = mPackageManager.getClass().getMethod(methodName, parameterType1, parameterType2);/** freeStorageSize : The number of bytes of storage to be freed by* the system. Say if freeStorageSize is XX, and the current free* storage is YY, if XX is less than YY, just return. if not free* XX-YY number of bytes if possible.*/Long freeStorageSize = Long.valueOf(getDataDirectorySize());freeStorageAndNotify.invoke(mPackageManager, freeStorageSize,new IPackageDataObserver.Stub() {@Overridepublic void onRemoveCompleted(String packageName,boolean succeeded) throws RemoteException {}});} catch (Exception e) {e.printStackTrace();}}获取方法时用的是:
getMethod()
果断试试换种写法:/*** 取得指定包名的程序的缓存大小*/private void queryPkgCacheSize(String pkgName) throws Exception {if (!TextUtils.isEmpty(pkgName)) {// pkgName不能为空// 使用放射机制得到PackageManager类的隐藏函数getPackageSizeInfoif (mPackageManager == null) {mPackageManager = getBaseContext().getPackageManager();// 得到被反射调用函数所在的类对象}try {String methodName = "getPackageSizeInfo";// 想通过反射机制调用的方法名Class<?> parameterType1 = String.class;// 被反射的方法的第一个参数的类型Class<?> parameterType2 = IPackageStatsObserver.class;// 被反射的方法的第二个参数的类型Method getPackageSizeInfo = mPackageManager.getClass().getMethod(methodName, parameterType1, parameterType2);getPackageSizeInfo.invoke(mPackageManager,// 方法所在的类pkgName, mStatsObserver);// 方法使用的参数} catch (Exception ex) {Log.wtf("tag", "queryPkgSize()-->NoSuchMethodException");ex.printStackTrace();throw ex; // 抛出异常}}}/*** 使用Android系统中的AIDL文件,获得指定程序的大小。AIDL文件形成的Binder机制*/private IPackageStatsObserver.Stub mStatsObserver = new IPackageStatsObserver.Stub() {@Overridepublic void onGetStatsCompleted(PackageStats pStats, boolean succeeded)throws RemoteException {long tmp = totalCacheSize;totalCacheSize += pStats.cacheSize;// 累加if (tmp != totalCacheSize) {// 总缓存大小有变化mHandler.sendEmptyMessage(MSG_UPDATE_TOAST_TEXT);}}};果然,
totalCacheSize
就能获取到相对应的数值。问题解决。不过,我也没发现这个getMethod()和
getDeclaredMethod()
差异性在哪里?getDeclaredMethod*()获取的是类自身声明的所有方法,包含public、protected和private方法。getMethod*()获取的是类的所有共有方法,这就包括自身的所有public方法,和从基类继承的、从接口实现的所有public方法。 平常没留心,这时候很容易出错。这两个不是可以随意更换的。上源码:http://download.csdn.net/detail/yql44137228/7676871
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐