Android 阿里百川 AAR 与支付 SDK 的 configChanges 冲突
结论
这类问题通常不需要更换支付 SDK。可以在应用自己的 AndroidManifest.xml 中,为发生冲突的 Activity 明确指定最终的 android:configChanges,再通过 Manifest Merger 的 tools:replace="android:configChanges" 覆盖 AAR 中的声明。
最终值建议取两个 AAR 配置项的并集,以免覆盖时遗漏某些配置变化。冲突的 Activity 名称和具体属性值,应以 Gradle 构建日志为准。
冲突原因
alipaySdk-15.7.9-20200727142814-noUtdid.aar 和 nb_trade-4.0.0.8.aar 都在各自的 Manifest 中声明了同一个支付相关 Activity,但两处 android:configChanges 的值并不完全一致。
例如,一个 AAR 可能声明:
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
另一个 AAR 可能声明:
android:configChanges="orientation|keyboardHidden|navigation"
Manifest Merger 无法自行确定应该保留哪个值,因此会导致构建失败。所谓“不冲突版本”通常只适用于特定的依赖组合。如果项目中还有旧版传递依赖、重复的本地 AAR,或者百川 SDK 内部带有另一份支付组件,冲突依然可能出现。
解决步骤
1. 确认发生冲突的 Activity
先查看完整的 Manifest 合并错误,通常会出现类似信息:
Attribute activity#com.alipay.sdk.app.H5PayActivity@configChanges
value=(...)
is also present at ...
Suggestion: add 'tools:replace="android:configChanges"'
请使用日志中显示的完整类名,不要根据 AAR 文件名猜测。
还可以生成依赖树,检查项目是否同时引入了多个支付宝 SDK:
./gradlew app:dependencies
如需检查具体配置,可以执行:
./gradlew app:dependencyInsight \
--configuration debugRuntimeClasspath \
--dependency alipay
如果模块名不是 app,请替换为实际的模块名称。
2. 在应用 Manifest 中覆盖冲突属性
在应用模块的 AndroidManifest.xml 根节点中声明 tools 命名空间:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application>
<activity
android:name="com.alipay.sdk.app.H5PayActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
tools:replace="android:configChanges" />
</application>
</manifest>
这里的 android:name 必须与构建日志中报告的冲突组件完全一致。
如果日志显示多个 Activity 存在冲突,需要分别覆盖。例如:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application>
<activity
android:name="com.alipay.sdk.app.H5PayActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
tools:replace="android:configChanges" />
<activity
android:name="com.alipay.sdk.app.H5AuthActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
tools:replace="android:configChanges" />
</application>
</manifest>
不要直接照搬第二个示例中的类名。只有合并日志明确报告该组件发生冲突时,才需要添加对应声明。
3. 使用配置项并集
假设两个 AAR 分别声明:
orientation|keyboardHidden|navigation
和:
orientation|keyboardHidden|navigation|screenSize
应用层可以使用两者的并集:
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
tools:replace 会让 Manifest Merger 使用应用 Manifest 中的值作为最终结果,但不会自动合并两个字符串,因此需要手动写出完整配置。
4. 排查重复 SDK
如果项目既手动放置了 AAR,又通过 Maven 依赖引入了相同组件,应删除其中一份。可以检查:
app/libs/alipaySdk-*.aar
app/libs/nb_trade-*.aar
同时检查 build.gradle 中是否还有对应依赖:
dependencies {
implementation files('libs/alipaySdk-15.7.9-20200727142814-noUtdid.aar')
implementation files('libs/nb_trade-4.0.0.8.aar')
}
如果 nb_trade 已经包含支付 SDK,或者会传递引入支付 SDK,再手动添加支付宝 AAR 就可能造成重复。对于 Maven 传递依赖,可以先从依赖树中确认模块名称,再将其排除:
dependencies {
implementation('实际的百川依赖坐标') {
exclude group: '实际的group', module: '实际的module'
}
}
不能根据 AAR 文件名推断 group 和 module,必须使用依赖树中的真实坐标。本地通过 files(...) 引入的 AAR 无法使用 exclude 排除,只能调整 libs 目录或依赖声明。
验证方式
修改后重新构建:
./gradlew clean
./gradlew app:assembleDebug
然后在 Android Studio 的 Merged Manifest 中检查目标 Activity,确认最终只有一条声明,并且 android:configChanges 与预期一致。
注意事项
tools:replace必须写在发生冲突的组件节点上。只在<manifest>中声明xmlns:tools不能解决冲突。- 不建议使用
tools:node="remove"直接删除支付Activity,否则支付页面可能无法打开,回调也可能出现异常。 - 不要随意使用
tools:node="replace"替换整个Activity。这样可能同时覆盖 AAR 中的theme、launchMode、exported等属性。如果只有configChanges冲突,使用tools:replace="android:configChanges"更合适。 - 如果处理后又出现其他属性冲突,可以逐项覆盖,例如:
tools:replace="android:configChanges,android:theme"
前提是应用 Manifest 已经明确写出了这些属性的最终值。
- 是否必须保留
screenSize等配置项,取决于 SDK 处理配置变化的方式。没有官方明确说明时,使用两个声明的并集通常更安全。 - 如果合并日志报告的不是同一个
Activity的属性冲突,而是Duplicate class,说明项目存在重复类。此时tools:replace无法解决问题,必须删除或排除重复的支付 SDK。
备注:内容仅供参考。
