您的位置:首页 > 移动开发 > Android开发

解决 Android L getConstructor 报 java.lang.NoSuchMethodException:

2015-04-16 18:58 447 查看
先说说换肤功能,我这换肤功能就是去获取apk的资源文件
详细请看这篇文章:android从未安装的apk文件里获取信息(包信息,资源信息)
我手机系统是android 5.0.2 今天调试的时候发现软件的换肤功能“坏了”,再跟下去发现我手机在调用getConstructor时
会报 java.lang.NoSuchMethodException: ,但其他手机没问题,初步断定是系统版本问题。
网上查半天也没结果 直到看到
Android L反射扫描不到包名原因

最后解决了附上代码:
public static Resources getApkFileInfo(Context ctx, String apkPath) {
        System.out.println(apkPath);
        File apkFile = new File(apkPath);
        if (!apkFile.exists() || !apkPath.toLowerCase().endsWith(".apk")) {
            System.out.println("file path is not correct");
            return null;
        }

        String PATH_PackageParser = "android.content.pm.PackageParser";
        String PATH_AssetManager = "android.content.res.AssetManager";
        try {
            //VERSION_CODES LOLLIPOP
            Object pkgParser;
            Class pkgParserCls = Class.forName(PATH_PackageParser);
            Constructor<?> pkgParserCt;
            Class<?>[] typeArgs = { String.class };
            Object[] valueArgs = { apkPath };
            Method pkgParser_parsePackageMtd;
            Object pkgParserPkg;
            if (Build.VERSION.SDK_INT >= 21) {
                pkgParserCt = pkgParserCls.getConstructor(null);
                pkgParser = pkgParserCt.newInstance(null);
                typeArgs = new Class[2];
                typeArgs[0] = File.class;
                typeArgs[1] = Integer.TYPE;
                pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod("parsePackage",typeArgs);

                valueArgs = new Object[2];
                valueArgs[0] = new File(apkPath);
                valueArgs[1] = 0;

                pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser, valueArgs);
            } else {
                pkgParserCt = pkgParserCls.getConstructor(typeArgs);
                pkgParser = pkgParserCt.newInstance(valueArgs);

                typeArgs = new Class<?>[] { File.class, String.class, DisplayMetrics.class, int.class };
                pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod("parsePackage", typeArgs);

                DisplayMetrics metrics = new DisplayMetrics();
                metrics.setToDefaults();

                valueArgs = new Object[4];
                valueArgs[0] = new File(apkPath);
                valueArgs[1] = apkPath;
                valueArgs[2] = metrics;
                valueArgs[3] = 0;

                pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser, valueArgs);
            }

            if (pkgParserPkg == null) {
                return null;
            }
            Field appInfoFld = pkgParserPkg.getClass().getDeclaredField("applicationInfo");

            if (appInfoFld.get(pkgParserPkg) == null) {
                 return null;
            }
            ApplicationInfo info = (ApplicationInfo) appInfoFld.get(pkgParserPkg);

            Class<?> assetMagCls = Class.forName(PATH_AssetManager);
            Object assetMag = assetMagCls.newInstance();
            typeArgs = new Class[1];
            typeArgs[0] = String.class;
            Method assetMag_addAssetPathMtd = assetMagCls.getDeclaredMethod("addAssetPath", typeArgs);
            valueArgs = new Object[1];
            valueArgs[0] = apkPath;
            assetMag_addAssetPathMtd.invoke(assetMag, valueArgs);

            Resources res = ctx.getResources();
            typeArgs = new Class[3];
            typeArgs[0] = assetMag.getClass();
            typeArgs[1] = res.getDisplayMetrics().getClass();
            typeArgs[2] = res.getConfiguration().getClass();
            Constructor<Resources> resCt = Resources.class.getConstructor(typeArgs);
            valueArgs = new Object[3];
            valueArgs[0] = assetMag;
            valueArgs[1] = res.getDisplayMetrics();
            valueArgs[2] = res.getConfiguration();
            res = (Resources) resCt.newInstance(valueArgs);

            if (info != null) {
                if (info.icon != 0) {
                    Drawable icon = res.getDrawable(info.icon);// 图标
                }
                if (info.labelRes != 0) {
                    String neme = (String) res.getText(info.labelRes);// 名字
                } else {
                    String apkName = apkFile.getName();
                }
                String pkgName = info.packageName;// 包名
            } else {
                 return null;
            }
            PackageManager pm = ctx.getPackageManager();
            PackageInfo packageInfo = pm.getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES);
            if (packageInfo != null) {
            }
            return res;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐