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

Android 插件化开发之获取APK的代码与资源

2016-12-04 22:43 471 查看
插件化开发,可以分为3种形式:1,通过下载zip文件来应用资源。2,通过下载并安装APK来应用资源。3,通过下载但不安装APK的方式来应用资源。 第一种比较简单,就不做介绍了。

获取已安装的APK中的资源和代码

获取未安装的APK中的资源和代码

1.获取已安装的APK中的资源和代码

1.1获取插件APK的Context

Context packageContext = createPackageContext(pkName, Context.CONTEXT_INCLUDE_CODE
| Context.CONTEXT_IGNORE_SECURITY)


1.2.获取代码

根据该Context获取到ClassLoader,有了ClassLoader,我们也可以去反射APK中的代码,然后就可以为所欲为了。(混淆类或者类方法被混淆,就无能为力了)

1.3.获取资源

根据该Context获取到Resource,有了Resource对象,我们就可以去加载插件APK中的资源文件。获取资源过程需要资源ID,但是主程序如何获取到插件APK的资源ID呢?方式有几种:

1.插件APK将ID保存在SharePreference等中并设置和主程序使用相同的shareUserId和签名,然后主程序去获取该ID。

2.通过反射R.java中的静态类(如drawable类),获取想要的某field值(如ic_launcher)。(混淆R文件或者混淆R文件中的静态类,就无能为力了)

3.通过getResources().getIdentifier(drawableName, “drawable”,context.getPackageName())方式获取。

2获取未安装的APK中的资源和代码

安卓中context.getResource()获取到的Resource对象其实是指向当前程序在沙盒(/data/data/程序包名.apk)中的apk,该resource只能获取当前程序的资源,无法获取到其他程序的资源。这就需要我们想办法得到一个能获取其他apk资源的Resource对象。跟踪context.getResource()源码会发现,内部有一段代码大致意思如下

AssetManager assetManager = new AssetManager();



assetManager.addAssetPath()//该方法需要传入assetPath,该assetPath就是context对应的ApplicationInfo.sourceDir值(即/data/data/程序包名.apk)。

依照该思路,我们加入未安装的apk的path进去,并创建一个新Resource对象,该对象就能获取插件APK中的资源对象了。

2.1.获取指向插件APK的Resource对象

AssetManager assetManager = AssetManager.class.newInstance();
Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
addAssetPath.invoke(assetManager, dexPath_tmp);

Resources superRes = mContext.getResources();
Resources skinResource=new Resources(assetManager, superRes.getDisplayMetrics(), superRes.getConfiguration());


2.2.获取插件APK的代码

通过DexClassLoader来加载未安装的APK的类,并执行相关代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: