background
Sometimes when a new SDK is introduced, the build will have the following problems:
Caused by: com.android.dex.DexException: Multiple dex files define Lcom/google/gson/internal/bind/TypeAdapters;
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 10s
81 actionable tasks: 8 executed, 73 up-to-date
Copy the code
What this means is that repeated dex files appear in the TypeAdapters class.
Simply put, repeated dependencies or dependency conflicts or Jar conflicts.
The solution
In addition to removing conflicting packages, we can also use Gradle’s exclude group to exclude the specified package name from the compilation range, as shown below:
Implementation ('cn.bmob. Android :bmob- SDK :3.5.5'){// implementation -2.6.2 exclude group: 'com.squareup. Okhttp3 'exclude group: 'com.squareup.okio' exclude group: 'com.google.code.gson' //exclude(module: 'gson') // Exclude (module: 'gson')Copy the code
Several ways that Android gets all of its dependent libraries
Method 1: Run the dependencies command
./gradlew :app:dependencies
Note: App refers to the project’s app directory. If your project does not have an APP directory, change the app to the name of your project’s actual directory.
The task displays output like this:
The output lists all the dependency trees in the configuration. The dependency relationships are clear and hierarchical. If you find the output too verbose (typically dozens of configurations), you can specify a configuration to display a specific dependency tree:
./gradlew :app:dependencies --configuration releaseCompileClasspath
This command only displays the dependency tree during compilation in release mode.
Method 2: Run the androidDependencies command
./gradlew :app:androidDependencies
The output is as follows:
As shown in the figure, the task will tile the dependency tree and only show a few major Variants, which looks relatively clean, but the disadvantage is that the configuration cannot be specified as in Mode 1.
Method 3: Obtain a user-defined task
project.afterEvaluate { project.android.applicationVariants.all { variant -> tasks.create(name: "showDependencies${variant.name.capitalize()}", description: "Show all dependencies ") {doLast {Configuration Configuration try {// 3.x Configuration = project.configurations."${variant.name}CompileClasspath" } catch (Exception e) { // 2.x configuration = project.configurations."_${variant.name}Compile" } configuration.resolvedConfiguration.lenientConfiguration.allModuleDependencies.each { def identifier = it.module.id println("${identifier.group}:${identifier.name}:${identifier.version}") } } } } }Copy the code
As shown in the preceding section, you can choose to print dependencies or save them to a file in this custom task mode, which is the most flexible.
Conclusion:
Method 1: Common Task: displays the dependency tree by hierarchy. You can specify the configuration to filter output. Method 2: Android project-specific tasks that tiled the dependency tree and did not filter the output. Method 3: Custom task to obtain dependencies is the most flexible, but requires a deep understanding of Gradle.
The solution to repeated dependencies
1.Program type already present: android.support.design.widget.CoordinatorLayout$1
The Design module needs to be removed from all support packages
Implementation (' com. Android. Support: appcompat - v7:27.1.0 ', {exclude group: 'com. Android. The support, the module: 'design'}) implementation (' com. Android. Support: recyclerview - v7:27.1.0 ', {exclude group: 'com. Android. The support, the module:' design '}) implementation (' com. Android. Support: cardview - v7:27.1.0 ', {exclude group: 'com. Android. The support, the module:' design '}) implementation (' com. Android. Support: customtabs: 27.1.0 ', {exclude group: 'com.android.support', module: 'design' })Copy the code
The version of the design package is the same as that of the previous support package
Implementation ‘com. Android. Support: design: 27.1.0’
Then Sync → Clean → Build APK.
There are two main ways to resolve dependencies
Exclude mode
Features:
- Configuration is cumbersome and excludes each dependency that causes the conflict
- The configuration is tedious and unattractive
The following is also possible.
Implementation 'org. Eclipse. Paho: org. Eclipse paho. Client. Mqttv3:1.0.2' Implementation (' org. Eclipse. Paho: org. The eclipse paho. Android. Service: 1.0.2 ') {exclude (group: 'com.google.android', module: 'support-v4')} No above the pit of the implementation (' org. Eclipse. Paho: org. Eclipse paho. Android. Service: 1.0.2 ') {exclude module: 'support - v4'} * /Copy the code
You need to configurations
Features:
- In configurations, you specify how you want to configure
- The configuration is simple and neat
Find the root cause of the problem of dependence on the elimination, according to the prompt error to flexibly deal with the conflict problem! The following is also possible.
Configurations {all*. Exclude group: 'com.google.android', module: 'support-v4' 'support-v4' }Copy the code
Configurations. All The same version
configurations.all { resolutionStrategy { force "com.android.support:support-v4:$android_support_version" force "com.android.support:appcompat-v7:$android_support_version" force "com.android.support:constraint-layout:$android_support_version" force "com.android.support:support-core-utils:$android_support_version" force "Com. Android. Support: exifinterface: $android_support_version" force "com. Google. Code. Gson: gson: 2.7"}}Copy the code