Android 项目多个 Jar 包有命名空间冲突,有办法解决吗?

2021-04-21 09:23:17 +08:00
 Moyudawang

简单来说,同一个芯片的 SDK 被两个硬件组装厂家做了封装,我们的项目添加两个 Module 分别引用两个厂家封装后的 SDK(jar 、so),然后他们引用的芯片 SDK 就出现命名空间冲突了,而且他们用的芯片 SDK 版本还不一样,让厂家修改也不现实。
现在就一直报错几个 Module 引用的 Jar 文件中有相同的内容,
尝试把 Module 编译成 dex 动态加载,可是 dex 不能把 jar 和 so 打包进去,
有没有大佬遇到过这种问题?望赐教

6706 次点击
所在节点    Android
38 条回复
kingiis
2021-04-21 13:15:15 +08:00
看你说涉及到了 so 文件
只能从源码层面 二次开发重新导出
ParfoisMeng
2021-04-21 13:51:13 +08:00
为啥让厂家修改不现实……
p2pCoder
2021-04-21 14:03:09 +08:00
maven 有 maven-shade,gradle 应该也有类似的工具
Moyudawang
2021-04-21 14:14:00 +08:00
@kingiis 没有源码,也没有这个能力
@ParfoisMeng 因为让他们改过,有的改过也不行,有的说改不了,例如设备上的扫描头模块,很多组装厂家用的是一样的模块,但是为了连接他们的硬件又把扫描头的 sdk 封装了一层,要改大家全都一起改,太难了
@p2pCoder 这还真不知道
Moyudawang
2021-04-21 14:17:55 +08:00
@ParfoisMeng 也怪我们采购了太多种类的设备,厂家提供的 sdk 都是大一统集成在一起的(RFID 、NFC 、条码扫描头),用起来是方便,冲突了就麻烦了
xFrye
2021-04-21 14:24:00 +08:00
没有包名检测的话,用 jarjar 就好,之前接一个第三方库也有个冲突的,给他命名空间改了
Moyudawang
2021-04-21 14:47:21 +08:00
@xFrye 有些方法是用 JNI 调用的,包名不能改
2bab
2021-04-21 14:53:42 +08:00
1. 编译期解决的话,改命名空间最快
2. 运行期解决的话,我依旧推荐动态加载 + 区分 Classloader,打不出 Dex 多半只是姿势问题,懒得研究的话,你可以直接建一个全空的 Android 工程,就引用这个 SDK,然后打了 APK 再把 Dex 给解压出来
Moyudawang
2021-04-21 15:34:29 +08:00
@2bab 嗯,我也觉得动态加载才是根本解决办法,我再研究研究 dex,多谢提醒
ParfoisMeng
2021-04-21 17:47:30 +08:00
@Moyudawang 如果是版本不统一属实难搞,可以和每个厂家约定统一使用最新稳定版本。然后都打 without 包( compileOnly )出来,你自己去依赖指定版本。
humpy
2021-04-21 17:56:08 +08:00
littlewing
2021-04-21 21:20:00 +08:00
@xne110 并不是,而是两个同名的包是不同功能,而且两个都需要用到
limbo0
2021-04-22 01:13:04 +08:00
maven-shade 正解, 把 A 厂家的包 shade 成 a.com.x.x , B 厂家的包 shade 成 b.com.x.x, build 完后引入你的项目, 互不影响
Moyudawang
2021-04-22 08:09:18 +08:00
@ParfoisMeng 有的设备都是几年前的了,厂家懒得搞

@humpy 感谢指点
@limbo0 谢谢 我会去试试
lqw3030
2021-04-22 09:25:52 +08:00
独立类加载器加载
Aviciii
2021-04-22 09:55:39 +08:00
我遇到过项目需要引用不同版本的 jar 包,最后用的 jarjar.jar 改的包名,然后把相关引用也改掉。不知道对你有没有帮助。
gam2046
2021-04-22 11:09:00 +08:00
假设 a.jar 包含 com.sample.MyClass,b.jar 包含 com.sample.MyClass,
a 与 b 的功能完全不同,则可以考虑在编译时,不引入 a.jar 与 b.jar

在使用期间(运行期间)通过不同的 ClassLoader 分别加载 a 与 b 即可
对应到 Android 即 BaseDexClassLoader 。

缺点是需要通过反射调用 a 与 b 的方法,当然如果他们有共同实现的接口或共同的父类,可以把这个这个接口或类放到主 jar 中,可以方便调用。
Wounmay9976
2021-04-22 11:59:39 +08:00
感觉#14 是开发最优,要是能接受这样最简单快捷。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/772085

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX