lilidejing
lilidejing
> 粗看9万行数据是明显意料之外的吧。难道是你发了9万个版本了? 不是意外,线上已经很多用户反馈慢了,拿了几台设备都是几万条数据以上。 我们启动插件方法,是参考demo启动方法:[SamplePluginManager ](https://github.com/Tencent/Shadow/blob/master/projects/sample/maven/manager-project/sample-manager/src/main/java/com/tencent/shadow/sample/manager/SamplePluginManager.java)类的onStartActivity方法。每次用户点击启动插件,都会执行onStartActivity方法。经过启动插件模块时,观察数据库表发现,onStartActivity方法中这句代码:**InstalledPlugin installedPlugin= installPlugin(pluginZipPath, null, true); 每次执行后,数据库shadowPluginManager表中都会被插入4条数据**。 如图:  **请问我们启动插件模块的方法有问题吗?**
> dependsOn属性只是将这些插件的ClassLoader的parent关系指定一下,允许它们跨ClassLoader加载类。但一个Android app,也就是一个插件,它实际上还包含资源文件,so文件等。这些其他文件dependsOn属性是没有任何处理的。 > > 资源相关的接口一般都是从一个context对象上发起的,这个context肯定会对应一个插件,那它其实只能加载到自己打包的资源。 所以你应该检查一下那些找不到的资源ID是哪个插件里面的,它的context是哪个插件。 > > 更要注意的是,那些XML资源本身是支持继承的,如果要继承的两个文件处于两个不同的插件中,肯定是不行的了。 > > 但上面说的也只是现有代码的能力。如果你更进一步研究Android系统的资源加载机制,应该能发现它本来是有共享资源的设计的。所以才有资源ID分区的设计。所以理论上是能实现跨apk共享资源的。 > > 多插件的场景更复杂,也更需要你在使用前了解插件框架的方方面面。不能拿这个框架当黑盒用。 感谢您的回复!非常感谢! 我用shadow之前有去做过大量的了解,也了解dependOn的机制,现在遇到的问题比较疑惑。 如果dependsOn属性只是将这些插件的ClassLoader的parent关系指定一下,允许它们跨ClassLoader加载类,但是以下现象让我感到疑惑。 我将 sample-base和 sample-base-lib的 gradle文件中`buildFeatures { buildConfig = true viewBinding = true...
谢谢回复! 已找到最开始问题java.lang.IllegalArgumentException: View is not a binding layout. Tag: layout/layout_activity_skip2_0的根本原因。 我简单描述下场景: 1,插件之间的关系:插件A 依赖 插件B ,即插件A dependOn 插件B。, 2,布局文件layout_activity_skip2所在位置:在插件A中 3,插件A和插件B都允许使用dataBinding。 4,当编译时,插件A会生成一个类:androidx.databinding.DataBinderMapperImpl,里面会**存放**Tag: layout/layout_activity_skip2_0。 插件B也会生成一个类:androidx.databinding.DataBinderMapperImpl,里面是**未存放** Tag: layout/layout_activity_skip2_0。 **原因:** **因为存在dependOn的关系,所以运行时classLoader会用插件B的specialClassLoader去加载androidx.databinding.DataBinderMapperImpl,加载成功。 但实际上 加载的 androidx.databinding.DataBinderMapperImpl是插件B编译时生成的,里面不存在Tag: layout/layout_activity_skip2_0这个标签,所以就报了...
> 如果是因为多个插件有重名的DataBinderMapperImpl,而实际上它们又是不同的类。然后这些插件还有继承关系。为了让它们加载不冲突,我们应该是需要给这个类在不同插件里改名吧。可以试试用添加一个transform,在编译后改名。可以参考shadow的transform实现。 很不错的建议,谢谢! 实际上binding = DataBindingUtil.bind(findViewById(R.id.root)); 这句执行时,会到DataBindingUtil中的静态变量sMapper(DataBinderMapperImpl)中去找对应的tag,它一定会去找DataBinderMapperImpl对象,所以重命名DataBinderMapperImpl没有用。 所以实际上是 DataBindingUtil 这个类也存在 多个插件有重名的情况、又是不同的类、然后这些插件还有继承关系 。 但是 DataBindingUtil 属于系统的API,插件编译时不会编译到build目录下,用transform的方案无法重命名DataBindingUtil 。 如果万一要用transform方案去做 ,是不是要参考你的代理Activity方案transform去实现一个DataBindingUtil 代理才行? DataBindingUtil 部分源码参考: `package androidx.databinding; /** * Utility class to create {@link...
1,我们最后的处理方案是在 PluginClassloader里改加载逻辑,让DataBindingUtil 相关的类不走 类似双亲委派的逻辑了。可以解决以上DataBinding问题。 2,但是dependOn这种场景,又遇到了几个新问题。 这些新问题都通过在 PluginClassloader里改加载逻辑,改为 指定类不走 类似双亲委派的逻辑可以解决。 **问题来了:** 因为这种情况后续可能会遇到很多,所以我想问的是,**如果插件A 依赖 插件B ,即插件A dependOn 插件B 这种场景,我的PluginClassLoader能否都改为:插件A优先加载插件A自己的类,如果找不到,再走之前的逻辑,它会再加载 插件B的类 ?这样会有什么问题没?是否存在风险?** **我们的PluginClassLoader类的loadClass方法最终具体修改代码如下,帮忙看下是否存在风险**: ` override fun loadClass(className: String, resolve: Boolean): Class { var...
> Shadow现有实现中的dependOn特性只是为了满足最初业务需求而抽象出的通用设计。如果它不能满足你的需求,你随便怎么改都行的。Shadow并没有对ClassLoader有什么特殊的改动,所以你修改loadClass的逻辑和这个项目就没什么关系了。作为开源项目,我们要交流的是开源项目的代码相关的问题。 我们目前将 PluginClassLoader 的 loadClass 逻辑做了调整: 当走 dependsOn 逻辑时,不再采用双亲委派机制,而是优先从自身加载类。这个修改确实解决了之前提到的那些问题。 我们使用dependsOn的初衷是这样的: 在一个 plugin.zip 中包含多个子插件的场景下,业务插件通过 dependsOn 依赖公共插件。 所有业务插件共同使用的 **组件库、系统库或第三方库**,统一由公共插件以 **implementation** 方式依赖; 而业务插件本身仅以 **compileOnly** 的方式依赖这些库。 这样做的目的,是为了减少插件整体的包体积,避免多个业务插件重复打入相同的依赖库。 我想知道作者您设计dependsOn的初衷是否和我们想象的一样?