Expo SDK45下expo-av与react-native-track-player版本不兼容问题求解
问题核心原因
两个冲突叠加导致构建失败:
- Expo SDK 45 将全局Kotlin编译版本升级到1.6.0,内置
expo-av@11.x绑定的ExoPlayer版本为2.17.x,和旧版react-native-track-player(以下简称RNTP)内置的2.16.x及以下版本ExoPlayer存在类重复、方法签名不匹配的运行时冲突。 - 强行把
expo-av降级到SDK 44配套的10.2.1版本时,该版本是基于Kotlin 1.4.1编译的,和SDK 45全局要求的1.6.0 Kotlin元数据版本不匹配,就会抛出Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin错误。
可行解决方案(按推荐优先级排序)
方案1:对齐依赖版本(无原生侵入,稳定性最高)
不要降级expo-av,直接对齐两个库的ExoPlayer、Kotlin版本要求:
- 锁定expo-av为SDK 45官方配套版本,执行安装命令:
yarn add expo-av@~11.2.0
- 升级RNTP到适配ExoPlayer 2.17.x、兼容Kotlin 1.6+的版本,对应版本为
react-native-track-player@2.2.0-rc4及以上,该版本内置ExoPlayer和SDK 45版expo-av完全一致,不会出现类冲突:
yarn add react-native-track-player@2.2.0-rc4
- 执行依赖自动修复命令,对齐所有Exo官方依赖版本:
npx expo install --fix
- 清理构建缓存后重新触发EAS构建,本地预构建可先进入android目录执行
./gradlew clean清除旧编译产物。
注意:使用2.2.0-rc4版本RNTP时,若出现播放相关API报错,对照2.x版本变更说明调整少量调用即可,核心播放逻辑无破坏性改动。
方案2:全局覆盖编译版本(适用于暂时无法升级RNTP的场景)
如果必须保留旧版RNTP,通过自定义插件强制对齐全局编译规则:
- 在项目根目录
plugins文件夹下新建withCustomKotlinVersion.js文件,写入以下配置,将全局Kotlin版本强制锁定为SDK 45要求的1.6.0:
const { withProjectBuildGradle } = require('@expo/config-plugins'); module.exports = function withCustomKotlinVersion(config) { return withProjectBuildGradle(config, (config) => { if (config.modResults.language === 'groovy') { config.modResults.contents = config.modResults.contents.replace( /kotlinVersion\s*=\s*["'][\d.]+["']/, 'kotlinVersion = "1.6.0"' ); } return config; }); };
- 编辑项目根目录
app.json,在expo.plugins数组中加入自定义插件,同时强制RNTP使用和expo-av一致的ExoPlayer版本:
{ "expo": { "plugins": [ "./plugins/withCustomKotlinVersion.js", [ "react-native-track-player", { "androidImplementation": "exoplayer", "exoplayerVersion": "2.17.1" } ] ] } }
- 重装依赖、清理构建缓存后重新执行EAS构建即可。
注意:该方案下旧版RNTP调用高版本ExoPlayer可能存在隐藏API兼容问题,必须完整回归所有播放相关功能。
方案3:排除重复依赖(适用于完全不使用expo-av播放能力的场景)
如果项目中音视频播放能力全部由RNTP实现,expo-av仅用于权限申请、音频焦点管理等非播放操作,可以直接在构建时排除expo-av内置的ExoPlayer依赖,从根源避免冲突:
- 保持expo-av为SDK 45默认版本,在
plugins文件夹下新建withExcludeExoPlayerFromExpoAv.js文件:
const { createRunOncePlugin, withAppBuildGradle } = require('@expo/config-plugins'); const withExcludeExoPlayer = (config) => { return withAppBuildGradle(config, (config) => { if (config.modResults.language === 'groovy') { const excludeRule = ` configurations.all { exclude group: 'com.google.android.exoplayer', module: 'exoplayer-core' exclude group: 'com.google.android.exoplayer', module: 'exoplayer-ui' exclude group: 'com.google.android.exoplayer', module: 'exoplayer-common' } `; config.modResults.contents = config.modResults.contents + excludeRule; } return config; }); }; module.exports = createRunOncePlugin(withExcludeExoPlayer, 'exclude-exoplayer-av', '1.0.0');
- 将该插件加入
app.json的plugins数组,清理缓存后重新构建即可。
构建避坑要点
- 禁止跨SDK大版本降级Expo官方维护的原生依赖(比如SDK 45环境下强行使用SDK 44配套的expo-av),这类依赖和SDK的Kotlin、AndroidX编译版本、EAS构建环境原生配置强绑定,降级必然触发编译错误。
- 调整原生依赖后触发EAS构建时,建议追加
--clear-cache参数,清空云端旧构建缓存,避免缓存残留导致的非预期报错。
内容的提问来源于stack exchange,提问作者red
相关产品推荐
相关产品推荐

