本文同步自wing的地方酒馆javascript
最近在搞插件化,16年很火的东西,我又拖了1年才来研究,哈哈哈,正确下一个热门技术能提早一些吧。php
今天想跟你们讨论一下我在研究插件化过程当中,遇到的一个容易混淆的点,那就是资源访问。java
首先感谢下在插件化道路上的老司机,无私的奉献资料。android
看过不少插件化的文章,都提到了一大痛点是资源访问的问题。解决方法很通用,都是经过反射使用 AssetManager 的 addAssetPath 方法,把插件apk路径添加进去。再把系统的resource替换掉,就能够访问到资源了。spa
这时候,大部分博客会添加一句:.net
资源访问是一个痛点,因此用以上方式解决R引用插件
可是这里有一个及其容易混淆的地方,就是 “解决了R引用”,那么到底其实是解决了谁的R引用问题呢? 是宿主访问插件的资源呢,仍是插件访问插件的资源呢?code
为了讲解清楚我来画一张图:cdn
如上图在没有替换掉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资源。固然你要提供插件的包名。