木骰

关于Unity中将AndroidSupport库升级到AndroidX

项目升级UniWebview插件,打安卓包的时候编译报错,大概是这样:
Duplicate class android.support.v4.app.INotificationSideChannel found in modules core-1.0.0-runtime (androidx.core:core:1.0.0) and support-compat-27.1.1-runtime (com.android.support:support-compat:27.1.1)

一番搜索后得知这个是AndroidX 与 Support的冲突问题。
以前的Android开发会用到一个AndroidSupport库,项目里可能会引用类似 android-support-v7-appcompat,support-compat等库,这个貌似是安卓开发的一个基础库,集成了很多基础功能,所以用的很普遍,我们项目里接的一些SDK就用到了support-compat-27.1.1 和 support-core-utils-27.1.1两个jar包。
而2018年后Google推出了一个AndroidX依赖库,这个AndroidX完整包含了Support库的内容,并且Goolgle对旧的Support库将不再维护,后续的更新都将在AndroidX上进行。
因此很多SDK开发商也都将自己的Support依赖改为了AndoirdX,就像我们项目里这次要更新的这个UniWebView。为了顺利把这个插件更新上去,也为了项目以后能够顺利更新或接入其他SDK,有必要将项目中目前使用的support-compat和support-core-utils改为Androidx。

Alt text
新版本的UniWebview在它的 UniWebViewPostBuildProcessor.cs脚本中加入了这个androidx.browser:browser 依赖,想来应该就是这个依赖有引用了与我们项目这两个support包同名的androidx依赖,以至于打包编译的时候才会出现这个冲突问题。
搜索解决方案的时候看到Google有关于support向AndroidX迁移的相关文档:
https://developer.android.com/jetpack/androidx/migrate

Alt text
文档说需要将项目使用的support库升到28.0.0版本,一开始以为是要support28.0.0和androidX兼容使用的意思,并且网上查找的其他方案解读大多也是这个意思,我理解为项目中的三方包使用support28.0.0,而uniwebview使用androidX,是要把这两个包同时打到包里的意思,而实际上并不需要这样,也是这个地方坑了我好久。

注意文档里还有两个配置:

Alt text
useAndroidX是打包时的一个开关配置,要使用androidX需要把这个开起来。

enableJetifier=true 主要是这个配置,看描述意思是这个配置开起来后,打包编译的时候会将项目中的第三方库里引用的support相关依赖,通过重写二进制形式改写为对AndroidX的依赖,这个就很神奇了,原本以为第三方库对support的依赖都写在各自的jar包里,没法修改这部分代码,这也是我一开始一直追寻support与androidX兼容方案的主要原因。而现在看起来其实并不需要兼容。
使用这个配置后,第三方jar包里的引用都将直接被改为androidX,所以我们项目中只需要打进androidX这一个依赖库就行了,而对于原本的support-compat和support-core-utils引用,直接删除即可。
这两个配置UniWebview也已经在UniWebViewPostBuildProcessor.cs加好了,如果需要自己添加的话,则需要通过继承实现IPostGenerateGradleAndroidProject接口,在导出安卓工程的回调里,把这两个配置加到gradle.properties里。

为了保险起见还需要自己添加一下support-compat和support-core-utils对应androidx包名的引用。Google也有support和androidX之间包名和类名的映射文档:
包名映射:
https://developer.android.google.cn/jetpack/androidx/migrate/artifact-mappings
类名映射:
https://developer.android.google.cn/jetpack/androidx/migrate/class-mappings
查询到support-comport和support-core-utils对应的是androidx.core:coreandroidx.legacy:legacy-support-core-utils,这里也应证了报错中出现的androidx.core:core:1.0.0包名。
虽然咱们这通过UniWebview的依赖也已经把这两个包含进来了,但是为了保险起见,还是自己主动添加一下这两个依赖。
implementation ‘androidx.core:core:1.0.0’
implementation ‘androidx.legacy:legacy-support-core-utils:1.0.0’
把这两个引用添加到项目launcherTemplate.gradle文件的dependencies块中:

Alt text
(并去掉了对support28.0.0的引用)

成功打出来包,但是启动时闪退了,查找错误日志发现还有报错,大概是
android.support.v4.content.FileProvider Not Found这样,
前面我们已经通过enableJetifier=true这个配置把第三方包里的引用都改成androidX了,而这里还有support库Not Found的报错,应该是其他地方的一些配置没有改全,后来查找到时AndroidManifest.xml中有对这个包的引用,在通过查询Google的类名映射,将其改为 androidx.core.content.FileProvider,问题解决。
后面还有遇到一些其他的关于support相关引用NotFound的报错,也都是一些其他地方的引用,比如写在C#代码里通过new AndroidJavaClass形式获取的方式等,全都一样改掉就好。

— 于 共写了2666个字
— 文内使用到的标签:

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*