标准名字
Android插件化
DexClassLoader加载未安装的apk,提供资源供宿主app使用
网上有很多插件化的教程, 我看了很多教程, 都是android的, 没找到autojs的, 所以就翻译了一下, 并且画了一个简单明了的流程图
流程图
autojs版本
9.0.4
教程中可使用到的未安装app资源
- 图片
- 颜色
- 字符串
- activity_main.xml
代码讲解
1. 得到未安装的apk信息
// resourcePath就是sd卡上的app文件路径 function queryPackageInfo(resourcePath) { return context.getPackageManager().getPackageArchiveInfo(resourcePath, context.getPackageManager().GET_ACTIVITIES); }
2. 创建AssetManager实例
assetManager = Class.forName("android.content.res.AssetManager").newInstance();
3. 添加apk路径
let method = assetManager.getClass().getMethod("addAssetPath", Class.forName("java.lang.String")); // 反射设置资源加载路径 method.invoke(assetManager, resourcePath);
4. 构造出正确的Resource
resources = new Resources( assetManager, context.getResources().getDisplayMetrics(), context.getResources().getConfiguration() );
5. 实例化DexClassLoader
// 构造函数 // public DexClassLoader(String dexPath, String optimizedDirectory, String libraryPath, ClassLoader parent) // dexPath - 就是apk文件的路径 // optimizedDirectory - apk解压缩后的存放dex的目录,在4.1以后该目录不允许在sd卡上 // libraryPath - 本地的library // parent - 父加载器 new DexClassLoader(resourcePath, mDexDir, null, context.getClassLoader())
6. 加载类
cls = mResourceLoadBean.getClassLoader().loadClass(rClassName);
7. 获取资源id
cls = mResourceLoadBean.getClassLoader().loadClass(rClassName); resID = cls.getField(fieldName).get(null);
8. 获取资源实体
drawable = mResourceLoadBean.getResources().getDrawable(resourceID);
注意事项
- DexClassLoader第二个参数, 必须为私有目录, 并且不可为空
- activity_main.xml的文字居中, 在androi studio中是正常的, 动态加载使用activity.setContentView并没有居中
- java的类, 转为autojs的类, 内部成员最好挂到this上面
- assetManager的实例是宿主app创造出来的, 但是一定要反射设置资源加载路径, 为未安装的app, 因为插件化就是用未安装的app资源
声明
部分内容来自网络
本教程仅用于学习, 禁止用于其他用途