android 插件话加载,Android插件化(一) 动态加载技术

下面介绍的是动态加载未安装的apk.然后读取apk中图片,显示在宿主app中

1.首先准备换肤的apk

skindemo-debug.apk

skindemo2-debug.apk

这2个apk中都有一张图片,然后我们push这两个apk到sdcard中就可以

资源加载问题,怎么通过Resources 加载另外一个apk中的图片

/**

* 获取AssetManager 用来加载插件资源

*

* @param pFilePath 插件的路径

* @return

*/

private AssetManager createAssetManager(String pFilePath) {

try {

final AssetManager assetManager = AssetManager.class.newInstance();

final Class> assetManagerClazz = Class.forName(“android.content.res.AssetManager”);

final Method addAssetPathMethod = assetManagerClazz.getDeclaredMethod(“addAssetPath”, String.class);

addAssetPathMethod.setAccessible(true);

addAssetPathMethod.invoke(assetManager, pFilePath);

return assetManager;

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

//这个Resources就可以加载非宿主apk中的资源

private Resources createResources(String pFilePath) {

final AssetManager assetManager = createAssetManager(pFilePath);

Resources superRes = this.getResources();

return new Resources(assetManager, superRes.getDisplayMetrics(), superRes.getConfiguration());

}

3.宿主apk,动态换肤的点击事件代码

private boolean mChange = false;

private String skinType = “”;

private int APK_TYPE;

/**

* 替换bg

*/

public void replace(View view) {

if (!mChange) {

skinType = “skindemo-debug.apk”;

APK_TYPE = 1;

mChange = true;

} else {

skinType = “skindemo2-debug.apk”;

APK_TYPE = 2;

mChange = false;

}

final String path = Environment.getExternalStorageDirectory() + File.separator + skinType;

final String pkgName = getUninstallApkPkgName(this, path);

dynamicLoadApk(path, pkgName);

}

private void dynamicLoadApk(String pApkFilePath, String pApkPacketName) {

File file = getDir(“dex”, Context.MODE_PRIVATE);

//第一个参数:是dex压缩文件的路径

//第二个参数:是dex解压缩后存放的目录

//第三个参数:是C/C++依赖的本地库文件目录,可以为null

//第四个参数:是上一级的类加载器

DexClassLoader classLoader = new DexClassLoader(pApkFilePath, file.getAbsolutePath(), null, getClassLoader());

try {

final Class> loadClazz = classLoader.loadClass(pApkPacketName + “.R$drawable”);

//插件中皮肤的名称是skin_one

final Field skinOneField = APK_TYPE == 1 ? loadClazz.getDeclaredField(“skin_one”) : loadClazz.getDeclaredField(“skin_two”);

skinOneField.setAccessible(true);

//反射获取skin_one的resousreId

final int resousreId = (int) skinOneField.get(R.id.class);

//可以加载插件资源的Resources

final Resources resources = createResources(pApkFilePath);

if (resources != null) {

final Drawable drawable = resources.getDrawable(resousreId);

linearLayout.setBackgroundDrawable(drawable);

}

} catch (Exception e) {

e.printStackTrace();

}

}

/**

* 根据sdcard路径,获取未安装apk的信息

*

* @param context

* @param pApkFilePath apk文件的path

* @return

*/

private String getUninstallApkPkgName(Context context, String pApkFilePath) {

PackageManager pm = context.getPackageManager();

PackageInfo pkgInfo = pm.getPackageArchiveInfo(pApkFilePath, PackageManager.GET_ACTIVITIES);

if (pkgInfo != null) {

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(资料价值较高,非无偿)

最后

如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。谢谢。

最后针对Android程序员,我这边给大家整理了一些资料,包括不限于高级UI、性能优化、移动架构师、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技术;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

最后

如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。谢谢。

[外链图片转存中…(img-3UhUEyF5-1711550942248)]

最后针对Android程序员,我这边给大家整理了一些资料,包括不限于高级UI、性能优化、移动架构师、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技术;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
  • 11
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值