shifujun
shifujun
` /data/user/0//files/miguplugins/plugin-manager-app.apk/0x6ed667cc40`这个apk看起来还像是shadow项目输出的manager.apk。但是` /data/user/0/包名/[email protected]/0x6f7f2428c0`就完全不是Shadow项目生成的了。所以我推断你的项目里有其他流程"duplicate classes or playing wrongly with class loaders"。
> partKey==ky-plugin-take-delivery在map中找不到。此时map:{} 这里的map是已加载插件的partKey到插件的各种数据的map。所以从有partKey但是map为空来看,这是进程重启之后试图恢复之前的Activity的启动过程。 SDK有这样的逻辑来应对这种情况,但是看起来它没生效。 https://github.com/Tencent/Shadow/blob/0e5d9d8d935d296bc40555b07d8396ba539de214/projects/sdk/core/activity-container/src/main/java/com/tencent/shadow/core/runtime/container/PluginContainerActivity.java#L106 你可能需要检查一下你修改什么代码,导致这里有可能出现判断错误。可以Debug一下这里的代码,手工构造一些杀死进程的场景。
LayoutInflater就是通过Context找到对应Resources的,要不Context怎么叫“上下文”呢? 如果不用xml自动inflate出view,建议直接让插件暴露createView的Java接口给宿主调用。
文不对题吧?你很清楚你在跨插件依赖资源了。现有代码不支持这种场景。 每个插件的Resources都只包含自身的apk。实际上也包含宿主的apk,但不是为了让插件使用宿主资源,是应对系统查找宿主资源的。 跨apk复用资源,在android的设计中是可行的。
这些方法应该都是通用的,不管谁实现了都欢迎PR回来。 final的方法虽然不能override,但是可以修改调用的代码。比如原本调用的是`context.getString()',我们可以把它修改成`ShadowContext.getString(context)`静态方法调用,把原本被调用的对象当作参数传给静态方法。这样静态方法里想怎么修改这个调用都可以了。Shadow很多Transform都是这样做的。可以搜一下`redirectMethodCallToStatic`。 我这边要实现这些方法,也只能抽时间。而且现在新增的修改都尽量配上自动化测试,所以写起来更费事一点。我们可以合作完成这些方法的支持。像这样的提交: 0e5d9d8d 2b494707
另外你提到的ShadowActivity缺少的方法,如果它们来自于Context类型,应该也不需要特别支持。因为ShadowActivity是继承自Context类型的。出现这种错误的原因可能是你的compileSdk版本较低,Context类型上没有这些新增的方法。
粗看9万行数据是明显意料之外的吧。难道是你发了9万个版本了?
那就没什么奇怪的了。你每次启动插件都重新安装了一次插件zip包。 你需要的是先查询已安装的插件信息,按照你的业务升级逻辑判断要不要启动已安装的插件。
这个installPlugin方法作为基础的原子功能,额外添加某种去重逻辑是不合适的。假如相同uuid的part不被重复插入数据库,那可能无法满足回退到旧版本的场景。或者还可能存在考虑不到的情况。所以基础接口最好不做分支逻辑。 避免重复调用这个接口本身是比较容易的,并且是否调用和业务升级逻辑也是强相关的。
按照这个描述,应该没能排除是“神策plugin”先把类改坏了的情况。你可以先只应用shadow plugin测试一下。 类似的情况在业务中见过。有的字节码编辑plugin采用了asm工具,编辑时不像javassist一样验证类的合法性。 如果是shadow的问题,instrument transform的实际作用不大,建议自己多研究下怎么兼容。我这边最近不太方便调试,只有手机用。