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