编译时报错:
* What went wrong:
Execution failed for task ':app:transformClassesWithMultidexlistForDebug'.
> com.android.build.api.transform.TransformException: Error while generating the main dex list.
参考:
https://blog.csdn.net/mxiaoyem/article/details/81666686
https://blog.csdn.net/stupid56862/article/details/81130589
使用如下命令详细筛查:
gradlew assembleDebug --stacktrace
日志如下:
D:\Android\MyApplication\MyExample>gradlew assembleDebug --stacktrace
Starting a Gradle Daemon, 1 incompatible Daemon could not be reused, use --status for details
> Configure project :app
Could not find google-services.json while looking in [src/nullnull/debug, src/debug/nullnull, src/nullnull, src/debug, src/nullnullDebug]
registerResGeneratingTask is deprecated, use registerGeneratedResFolders(FileCollection)
Could not find google-services.json while looking in [src/nullnull/release, src/release/nullnull, src/nullnull, src/release, src/nullnullRelease]
registerResGeneratingTask is deprecated, use registerGeneratedResFolders(FileCollection)
Download https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint-gradle/26.1.2/lint-gradle-26.1.2.pom
Download https://dl.google.com/dl/android/maven2/com/android/tools/external/com-intellij/intellij-core/26.1.2/intellij-core-26.1.2.pom
.
.
.
Download https://dl.google.com/dl/android/maven2/com/android/tools/external/com-intellij/intellij-core/26.1.2/intellij-core-26.1.2.jar
Download https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint/26.1.2/lint-26.1.2.jar
Download https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint-api/26.1.2/lint-api-26.1.2.jar
Download https://jcenter.bintray.com/org/codehaus/groovy/groovy-all/2.4.12/groovy-all-2.4.12.jar
> Task :app:processDebugGoogleServices
Parsing json file: D:\Android\MyApplication\***\***\app\google-services.json
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:transformClassesWithMultidexlistForDebug'.
> com.android.build.api.transform.TransformException: Error while generating the main dex list.
* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:transformClassesWithMultidexlistForDebug'.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:100)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:70)
at
.
.
.
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.run(DefaultTaskPlanExecutor.java:98)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
Caused by: java.lang.RuntimeException: com.android.build.api.transform.TransformException: Error while generating the main dex list.
at com.android.builder.profile.Recorder$Block.handleException(Recorder.java:55)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:104)
at com.android.build.gradle.internal.pipeline.TransformTask.transform(TransformTask.java:212)
.
.
.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:110)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:92)
... 29 more
Caused by: com.android.build.api.transform.TransformException: Error while generating the main dex list.
at com.android.build.gradle.internal.transforms.D8MainDexListTransform.transform(D8MainDexListTransform.kt:127)
at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:221)
at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:217)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:102)
... 41 more
Caused by: com.android.builder.multidex.D8MainDexList$MainDexListException: com.android.tools.r8.errors.CompilationError: Program type already present: com.apkfuns.logutils.BuildConfig
at com.android.builder.multidex.D8MainDexList.generate(D8MainDexList.java:87)
at com.android.build.gradle.internal.transforms.D8MainDexListTransform.transform(D8MainDexListTransform.kt:114)
... 44 more
Caused by: com.android.tools.r8.errors.CompilationError: Program type already present: com.apkfuns.logutils.BuildConfig
at com.android.tools.r8.utils.ProgramClassCollection.resolveClassConflictImpl(ProgramClassCollection.java:64)
at com.android.tools.r8.utils.ProgramClassCollection.lambda$create$0(ProgramClassCollection.java:25)
at com.android.tools.r8.utils.ProgramClassCollection.create(ProgramClassCollection.java:24)
at com.android.tools.r8.graph.LazyLoadedDexApplication$Builder.build(LazyLoadedDexApplication.java:121)
at com.android.tools.r8.dex.ApplicationReader.read(ApplicationReader.java:122)
at com.android.tools.r8.dex.ApplicationReader.read(ApplicationReader.java:86)
at com.android.tools.r8.GenerateMainDexList.run(GenerateMainDexList.java:40)
at com.android.tools.r8.GenerateMainDexList.run(GenerateMainDexList.java:110)
at com.android.builder.multidex.D8MainDexList.generate(D8MainDexList.java:83)
... 45 more
发现如下错误信息:
Program type already present
分析与排查:
这多半是由于依赖包重复导致的冲突,把冲突包重复的依赖剔除就可以了。
Android项目目前很多是由Gradle远程依赖,建议通过查看依赖树来排查问题 。
例如我的 Android 工程主 Module 名称为 app 。我想查看依赖树,进入项目根目录,执行命令:
gradlew app:dependencies
Terminal中会打印出很多文字,如:
我们把这个依赖树分成如下几个区域:
其中黄色框框中的“com.stripe:stripe-android:10.2.1”是我在项目中直接依赖的;
红色框框中的design库和annotations库等则是stripe库中的依赖,是项目中的二级依赖;
绿色框框中的很多库则是上述二级依赖的子依赖,即项目的三级依赖;
蓝色框框为四级依赖;
以此类推,随着项目的增大,依赖树可达很多层级,层级越多,出现本篇文章中的问题的可能性就越大。
因此大多数情况下的冲突是因为,依赖库所依赖的其他库版本冲突。
我们现在以常用的recycle人view依赖库为例,简要介绍解决依赖冲突的方式:
implementation 'com.android.support:recyclerview-v7:26.1.0
| +--- com.android.support:support-annotations:26.1.0 (*)
| +--- com.android.support:support-compat:26.1.0 (*)
| \--- com.android.support:support-core-ui:26.1.0 (*)
解决方案:
1. 删除自己重复添加的依赖
如果是自己添加了多个重复的依赖包,删除即可
2. exclude: 剔除依赖
recyclerview 不想要依赖 com.android.support:support-annotations:26.1.0 可以如下操作:
implementation ('com.android.support:recyclerview-v7:26.1.0'){
exclude group: 'com.android.support', module: 'support-annotations' // 根据组织名 + 构建名剔除
// 你也可以分别通过 group 和 module 剔除 对应的模块。
}
执行后的依赖树结果为:
+--- com.android.support:recyclerview-v7:26.1.0
| +--- com.android.support:support-compat:26.1.0 (*)
| \--- com.android.support:support-core-ui:26.1.0 (*)
3. force: 强制指定依赖版本
例如,我想要所有 com.android.support:support-annotations:26.1.0 的依赖版本为 27.1.1 怎么办呢 ?
在只需要在 build.gradle 中加上 force true 即可 :
implementation("com.android.support:support-annotations:27.1.1"){
force true
}
执行后依赖树:
+--- com.android.support:recyclerview-v7:26.1.0
| +--- com.android.support:support-annotations:26.1.0 -> 27.1.1
| +--- com.android.support:support-compat:26.1.0 (*)
| \--- com.android.support:support-core-ui:26.1.0 (*)
可以看到多了 -> 27.1.1 . 也就是原依赖版本为 26.1.0 ,在工程中修改依赖为 27.1.1 。
4. transitive: 依赖传递特性
transitive : 依赖传递特性,使用的时候,通常设置为 false 。即关闭依赖传递
例如项目中不希望 recyclerview 使用它所依赖的库,只需要在 build.gradle 中加上 transitive false 即可:
implementation ('com.android.support:recyclerview-v7:26.1.0'){
transitive false
}
执行后查看依赖树的结果,recyclerview 的依赖都消失了。
+--- com.android.support:recyclerview-v7:26.1.0
当然这是一个危险的操作,因为缺少依赖,你可能无法正常编译。最好确认你项目中已经依赖了你所剔除在外的库。
上述操作等同于:
implementation('com.android.support:recyclerview-v7:26.1.0') {
exclude group : 'com.android.support'
}
因为 recyclerview 依赖的三个库组织名都是 com.android.support。
最后说明一下:解决冲突用的最多是 force 和 exclude