插件化技术:宿主访问插件资源
Posted 三精-大精wing
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了插件化技术:宿主访问插件资源相关的知识,希望对你有一定的参考价值。
本文同步自wing的地方酒馆
最近在搞插件化,16年很火的东西,我又拖了1年才来研究,哈哈哈,正确下一个热门技术能提前一些吧。
今天想跟大家讨论一下我在研究插件化过程中,遇到的一个容易混淆的点,那就是资源访问。
首先感谢下在插件化道路上的老司机,无私的奉献资料。
看过很多插件化的文章,都提到了一大痛点是资源访问的问题。解决方法很通用,都是通过反射使用 AssetManager 的 addAssetPath 方法,把插件apk路径添加进去。再把系统的resource替换掉,就可以访问到资源了。
这时候,大部分博客会添加一句:
资源访问是一个痛点,所以用以上方式解决R引用
但是这里有一个及其容易混淆的地方,就是 “解决了R引用”,那么到底实际上是解决了谁的R引用问题呢? 是宿主访问插件的资源呢,还是插件访问插件的资源呢?
为了讲解清楚我来画一张图:
如上图在没有替换掉Resources的时候。
由于每个apk只能访问自己的res,所以这时候使用hook newActivity创建的Activity对象,是无法访问到插件res的,虽然这个Activity确实是插件中的Activity,但是实际上是加载在宿主里的resource,所以也就是有个隔离,因此必须替换resource
当AddPath以后,关系就变成了如上图的关系,此时创建的Activity的实例,也就是宿主的顺理成章能拿到插件的资源。
混淆点就是在这里,在之前网上博客文章中说的解决了资源访问问题,实际上是指插件Activity不能访问插件本身的资源,而不是说宿主Activity访问插件的资源。
宿主Activity如何访问插件资源?
经过大量搜索,跟小伙伴讨论得知可以通过如下方式获得插件资源:
getResources().getString(getResources()
.getIdentifier("plugin", "string","com.your.name")),
Toast.LENGTH_SHORT).show();
这个方法是根据资源名称,来获取资源id,所以就可以根据id拿到资源了。
比如上面的例子就是通过getIdentifier()方法寻找名称为plugin的string资源。当然你要提供插件的包名。
以上是关于插件化技术:宿主访问插件资源的主要内容,如果未能解决你的问题,请参考以下文章
Android 插件化Hook 插件化框架 ( 通过反射获取 “宿主“ 应用中的 Element[] dexElements )
Android 插件化Hook 插件化框架 ( 合并 “插件包“ 与 “宿主“ 中的 Element[] dexElements | 设置合并后的 Element[] 数组 )