如何查看Gradle項目的依賴樹狀況-排查 Unable to merge dex問題

1、問題描述
今天在編寫代碼過程當中,引入了一個組內新的封裝庫,致使編譯衝突。以下所示:java

FAILURE: Build failed with an exception.react

* What went wrong:
Execution failed for task ':demo:transformDexArchiveWithExternalLibsDexMergerForDebug'.
> java.lang.RuntimeException: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dexandroid

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.sql

* Get more help at https://help.gradle.orgapi

BUILD FAILED in 8s
51 actionable tasks: 13 executed, 38 up-to-date
1
2
3
4
5
6
7
8
9
10
11
12
13
點擊 【Run with --stacktrace】 ,從新編譯查看詳細信息,以下:微信

FAILURE: Build failed with an exception.app

* What went wrong:
Execution failed for task ':demo:transformDexArchiveWithExternalLibsDexMergerForDebug'.
> java.lang.RuntimeException: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex微信支付

* Try:
Run with --info or --debug option to get more log output.gradle

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':demo:transformDexArchiveWithExternalLibsDexMergerForDebug'.
    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 org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51)
    at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:62)
    at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)
    at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:60)
    at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:97)
    at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:87)
    at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:52)
    at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
    at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
    at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
    at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.run(DefaultTaskGraphExecuter.java:248)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:241)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:230)
    at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.processTask(DefaultTaskPlanExecutor.java:123)
    at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.access$200(DefaultTaskPlanExecutor.java:79)
    at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:104)
    at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:98)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.execute(DefaultTaskExecutionPlan.java:626)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.executeWithTask(DefaultTaskExecutionPlan.java:581)
    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: java.lang.RuntimeException: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex
    at com.android.builder.dexing.DxDexArchiveMerger.mergeMonoDex(DxDexArchiveMerger.java:177)
    at com.android.builder.dexing.DxDexArchiveMerger.mergeDexArchives(DxDexArchiveMerger.java:118)
    at com.android.build.gradle.internal.transforms.DexMergerTransformCallable.call(DexMergerTransformCallable.java:97)
    at com.android.build.gradle.internal.transforms.ExternalLibsMergerTransform.transform(ExternalLibsMergerTransform.kt:121)
    at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:222)
    at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:218)
    at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:102)
    at com.android.build.gradle.internal.pipeline.TransformTask.transform(TransformTask.java:213)
    at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
    at org.gradle.api.internal.project.taskfactory.IncrementalTaskAction.doExecute(IncrementalTaskAction.java:46)
    at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:39)
    at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:26)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:121)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
    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: java.lang.RuntimeException: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex
    at com.android.builder.dexing.DxDexArchiveMerger.lambda$mergeMonoDex$0(DxDexArchiveMerger.java:171)
Caused by: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex
Caused by: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex
    at com.android.builder.dexing.DexArchiveMergerCallable.call(DexArchiveMergerCallable.java:72)
    at com.android.builder.dexing.DexArchiveMergerCallable.call(DexArchiveMergerCallable.java:36)
Caused by: com.android.dex.DexException: Multiple dex files define Landroid/support/v4/app/TaskStackBuilder$SupportParentable;
    at com.android.dx.merge.DexMerger.readSortableTypes(DexMerger.java:661)
    at com.android.dx.merge.DexMerger.getSortedTypes(DexMerger.java:616)
    at com.android.dx.merge.DexMerger.mergeClassDefs(DexMerger.java:598)
    at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:171)
    at com.android.dx.merge.DexMerger.merge(DexMerger.java:198)
    at com.android.builder.dexing.DexArchiveMergerCallable.call(DexArchiveMergerCallable.java:61)
    ... 1 more網站


* Get more help at https://help.gradle.org

BUILD FAILED in 6s
51 actionable tasks: 5 executed, 46 up-to-date

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83


告訴我由於 Multiple dex files define Landroid/support/v4/app/TaskStackBuilder$SupportParentable; 有多個 相同的 TaskStackBuilder 類致使編譯不了的。

其餘的support包都是27.1.1,這個support-v4-23.2.1,從哪裏來的?

咱們代碼的build.gradle文件中,都搜索不到23.2.1 是從哪裏來的。個人代碼中根本就沒有地方引用這個版本的support-v4-23.2.1,那麼咱們該如何查找這個這個版本的support-v4-23.2.1究竟是在哪裏引入的呢???

2、如何快速查看Gradle項目包依賴狀況?
經過上面的問題,咱們想查找這個這個版本的support-v4-23.2.1究竟是在哪裏引入的,就必須得把項目的gradle依賴樹的狀況獲知,如何獲知android項目的gradle依賴呢??能夠經過如下幾種方式來獲知。

2.1 執行命令 ./gradlew 模塊名:dependencies
好比個人項目是 demo工程編譯失敗的,因此咱們執行命令

gradlew :demo:dependencies
1


執行命令以後的輸出日誌以下所示,由於日誌太多,截取部分:

+--- com.xtc.data:data-new-sqlcipher:1.0.2
|    +--- net.zetetic:android-database-sqlcipher:3.5.7
|    \--- com.j256.ormlite:ormlite-core:4.48
\--- com.xtc.phone:data-phone:1.1.8
     +--- com.android.support:appcompat-v7:27.1.1 (*)
     +--- com.android.support:support-annotations:27.1.1
     +--- io.reactivex:rxandroid:1.2.1 (*)
     +--- com.facebook.fresco:fresco:0.12.0
     |    +--- com.facebook.fresco:drawee:0.12.0
     |    |    +--- com.android.support:support-v4:23.2.1
     |    |    |    \--- com.android.support:support-annotations:23.2.1 -> 27.1.1
     |    |    \--- com.facebook.fresco:fbcore:0.12.0
     |    +--- com.facebook.fresco:fbcore:0.12.0
     |    \--- com.facebook.fresco:imagepipeline:0.12.0
     |         +--- com.android.support:support-v4:23.2.1 (*)
     |         +--- com.facebook.fresco:imagepipeline-base:0.12.0
     |         |    +--- com.android.support:support-v4:23.2.1 (*)
     |         |    +--- com.parse.bolts:bolts-tasks:1.4.0
     |         |    +--- com.nineoldandroids:library:2.4.0
     |         |    \--- com.facebook.fresco:fbcore:0.12.0
     |         +--- com.parse.bolts:bolts-tasks:1.4.0
     |         +--- com.nineoldandroids:library:2.4.0
     |         \--- com.facebook.fresco:fbcore:0.12.0
     +--- com.facebook.fresco:animated-gif:0.12.0
     |    +--- com.android.support:support-v4:23.2.1 (*)
     |    +--- com.parse.bolts:bolts-tasks:1.4.0
     |    +--- com.facebook.fresco:fbcore:0.12.0
     |    \--- com.facebook.fresco:animated-base:0.12.0
     |         +--- com.android.support:support-v4:23.2.1 (*)
     |         +--- com.facebook.fresco:imagepipeline-base:0.12.0 (*)
     |         +--- com.parse.bolts:bolts-tasks:1.4.0
     |         +--- com.facebook.fresco:fbcore:0.12.0
     |         \--- com.facebook.fresco:imagepipeline:0.12.0 (*)
     \--- com.facebook.fresco:imagepipeline-okhttp3:0.12.0
          +--- com.squareup.okhttp3:okhttp:3.0.1 -> 3.4.1 (*)
          +--- com.facebook.fresco:fbcore:0.12.0
          \--- com.facebook.fresco:imagepipeline:0.12.0 (*)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38


由上面的依賴樹咱們能夠看出來,

com.android.support:support-v4:23.2.1 被 com.facebook.fresco:fresco:0.12.0、com.facebook.fresco:animated-gif:0.12.0引用了。而這兩個庫又被com.xtc.phone:data-phone:1.1.8引用了。

因此咱們在引用com.xtc.phone:data-phone:1.1.8的地方,將com.android.support:support-v4:23.2.1exclude掉便可正常編譯。以下所示:

 implementation libraries.data_phone
1
修改成如下便可。

    //implementation libraries.data_phone
    //data_phone裏面的fresco包含了com.android.support:support-v4:23.2.1
    implementation (libraries.data_phone){
       exclude group: 'com.android.support', module: 'support-v4'
    }
1
2
3
4
5


若是是直接依賴本地的project的話,也是能夠進行exclude,只是須要在project 外面再包一層,寫成以下所示:

implementation  project(':phone')
1
改成

 //data_phone裏面的fresco包含了com.android.support:support-v4:23.2.1
    implementation  (project(':phone')){
        exclude group: 'com.android.support', module: 'support-v4'
    }
1
2
3
4


從新編譯,查看下依賴關係。

\--- com.xtc.phone:data-phone:1.1.8
     +--- com.android.support:appcompat-v7:27.1.1 (*)
     +--- com.android.support:support-annotations:27.1.1
     +--- io.reactivex:rxandroid:1.2.1 (*)
     +--- com.facebook.fresco:fresco:0.12.0
     |    +--- com.facebook.fresco:drawee:0.12.0
     |    |    \--- com.facebook.fresco:fbcore:0.12.0
     |    +--- com.facebook.fresco:fbcore:0.12.0
     |    \--- com.facebook.fresco:imagepipeline:0.12.0
     |         +--- com.facebook.fresco:imagepipeline-base:0.12.0
     |         |    +--- com.parse.bolts:bolts-tasks:1.4.0
     |         |    +--- com.nineoldandroids:library:2.4.0
     |         |    \--- com.facebook.fresco:fbcore:0.12.0
     |         +--- com.parse.bolts:bolts-tasks:1.4.0
     |         +--- com.nineoldandroids:library:2.4.0
     |         \--- com.facebook.fresco:fbcore:0.12.0
     +--- com.facebook.fresco:animated-gif:0.12.0
     |    +--- com.parse.bolts:bolts-tasks:1.4.0
     |    +--- com.facebook.fresco:fbcore:0.12.0
     |    \--- com.facebook.fresco:animated-base:0.12.0
     |         +--- com.facebook.fresco:imagepipeline-base:0.12.0 (*)
     |         +--- com.parse.bolts:bolts-tasks:1.4.0
     |         +--- com.facebook.fresco:fbcore:0.12.0
     |         \--- com.facebook.fresco:imagepipeline:0.12.0 (*)
     \--- com.facebook.fresco:imagepipeline-okhttp3:0.12.0
          +--- com.squareup.okhttp3:okhttp:3.0.1 -> 3.4.1 (*)
          +--- com.facebook.fresco:fbcore:0.12.0
          \--- com.facebook.fresco:imagepipeline:0.12.0 (*)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29


移除了重複類以後,正常編譯。

2.2 經過Android Studio右側的Gradle面板上的dependencies命令
若是上面的命令方式你不習慣,你能夠經過Android Studio右側的Gradle面板上的dependencies命令執行,以下所示

如上圖,找到【 demo】工程,展開,而後找到【help】目錄,找到【dependencies】命令,點擊便可執行命令。以下所示

2.3 執行 gradlew build --scan 命令,生成
若是你嫌在命令行窗口展現觀看不友好,這裏還有一種體驗更好的方式。

輸入下面命令行:gradlew build --scan

編譯完成的時候,出現輸入框,提示咱們輸入 yes或者no

Do you accept the Gradle Cloud Services license agreement (https://gradle.com/terms-of-service)? [yes, no]
1


咱們輸入yes,而後繼續

Do you accept the Gradle Cloud Services license agreement (https://gradle.com/terms-of-service)? [yes, no]
yes
Gradle Cloud Services license agreement accepted.

Publishing build scan...
https://gradle.com/s/paiitjk7aaiqa

C:\CodeForAndroid\BigData>

1
2
3
4
5
6
7
8
9


咱們打開上面生成的連接: https://gradle.com/s/paiitjk7aaiqa,而後登錄網站便可。

登錄網站,而後查看具體的信息,以下所示:

登錄郵箱,查看剛纔收到的郵件,以下所示:


2.4 經過 gradle view 插件查看gradle依賴樹
以下圖所示,在Settings --> Plugins中,搜索 gradle view插件並安裝,下圖是我已經安裝好的截圖。


搜索不到的,能夠直接去 http://plugins.jetbrains.com 網站搜索,而後下載


http://plugins.jetbrains.com/plugin/7150-gradle-view 下載,以下所示


第一次安裝完後,須要重啓Android Studio ,重啓以後咱們來使用gradle view 插件

如上圖,找到View–>Tools Windows-Gradle View ,而後點擊便可執行。

三 總結
上面我介紹了四種查看Gradle項目依賴樹的狀況的方法,大家能夠本身選擇本身喜歡的。我的以爲插件仍是最好用的。

做者:歐陽鵬 歡迎轉載,與人分享是進步的源泉!
轉載請保留原文地址:https://blog.csdn.net/ouyang_peng/article/details/82590820

若是本文對您有所幫助,歡迎您掃碼下圖所示的支付寶和微信支付二維碼對本文進行打賞。

相關文章
相關標籤/搜索