我在尝试将React Native项目打包到生产apk时遇到以下异常(使用从here获取的配置运行gradlew assembleRelease):
* What went wrong:
Execution failed for task ':app:transformDexWithDexForRelease'.
> com.android.build.api.transform.TransformException:
com.android.ide.common.process.ProcessException:
java.util.concurrent.ExecutionException: com.android.dex.DexException:
Multiple dex files define Lcom/facebook/binaryresource/BinaryResource;
在尝试打包调试时,app似乎在模拟器上完美运行(通过运行react-native run-android或执行gradlew assembleDebug)。
这种情况发生在一个曾经正确打包的项目上(生产apk也是如此),但由于iOS专注的开发而暂时没有构建(我们每隔一段时间只运行一次react-native run-android确定没有任何东西被打破,显然这还不够)。在此期间,Android配置完全没有被触及或更改,所有更改都是对iOS应用程序或Javascript代码进行的(安装了一些新的npm软件包,但它们都是纯JS并且不需要任何链接)。
我上传了完整的gradle堆栈跟踪here。
我正在使用最新的react-native版本(0.55.4)并对版本16.3.2做出反应。还试过更新各种包,并运行gradlew clean。
非常感谢有关此事的任何帮助。我很乐意提供任何可能相关的配置段,我只是不知道提供什么,因为自上次工作以来没有更改与android相关的配置/代码。
谢谢!
我会在这里为其他可能需要帮助的人提供这个。
在android / app / build.gradle上,在defaultConfig对象下放了这个标签:multiDexEnabled true
,如果这开始引发一个zip错误,把它放在文件的末尾
configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
def requested = details.requested
if (requested.group == 'com.android.support') {
if (!requested.name.startsWith("multidex")) {
details.useVersion '27.1.0'
}
}
}
}
当我遇到multiDex问题时,这对我有用,可能对每个人都不起作用
这是一种可以帮助诊断问题的方法。
在最终错误消息之前,您将获得Gradle尝试合并的JAR文件列表(通常在android\app\build\intermediates\transforms\preDex\release
中)。这些JAR文件中的每一个都来自您项目的某些依赖项。
您可以解压缩JAR文件并查找导致冲突的类的名称。在我的情况下,它是INotificationSideChannel
,在提问者的是BinaryResource
。
! grep INotificationSideChannel * -irl
50/classes.dex
80/classes.dex
所以冲突发生在50.jar
和80.jar
之间。查看提取的目录,有50/META-INF/com.android.support_support-compat.version
和80/META-INF/androidx.core_core.version
文件,表明这些文件分别代表com.android.support:support-compat
和androidx.core:core
依赖项。
为了记录,AndroidX意味着替代Android支持库,因此在构建中同时使用它们会导致冲突是有道理的。是时候检查项目依赖树了:
! gradlew app:dependencies
通过列表我可以看到androidx
只需要一次,通过com.google.android.gms:play-services-gcm:17.0.0
依赖,而react-native-device-info
引用。
一个小的谷歌搜索表明play-services-gcm
曾经在com.android.support
中引用16.1.0
,这导致我在android / build.gradle中的以下片段解决了我的问题:
subprojects {
project.configurations.all {
resolutionStrategy.eachDependency { details ->
// normalize com.android.support library versions
if (details.requested.group == 'com.android.support'
&& !details.requested.name.contains('multidex') ) {
details.useVersion "28.0.0"
}
// downgrade play-services-gcm version to avoid referencing androidx
if (details.requested.group == 'com.google.android.gms' &&
details.requested.name == 'play-services-gcm') {
details.useVersion "16.1.0"
}
}
}
...
如果您的冲突JAR没有.version文件,您可以尝试从jar中的类文件夹结构中识别它们(例如,okhttp3 / internal将引导您进入okhttp3),Gradle日志中冲突类的名称,或者您可以删除两个JAR并在日志中查找线索。
多个dex文件定义的错误...当你有MultiDex和重复的库时发生..
假设你已经通过support-v4
文件添加了一个aar
库,并且还使用了gradle。
Thistle导致gradle添加两者并发生错误。
您应该查找可能已添加两次的库。
在我的情况下,aar
和它的classes.jar
都添加了multidex启用,所以这发生了。