App 运行 顺利但构建 peekaboo 集成失败?

App running smoothly but failed in build peekaboo integration?

我在我的 cordova 应用程序中集成了 peekaboo,当我 运行 我的移动应用程序 运行 正常并且每个功能都正常工作但是当我开始在 android studio 中构建源代码时它给出以下错误。

Error converting bytecode to dex:
Cause: com.android.dex.DexException: Multiple dex files define 
Lokhttp3/internal/ws/WebSocketReader$FrameCallback;
Message{kind=ERROR, text=Error converting bytecode to dex:
Cause: com.android.dex.DexException: Multiple dex files define 
Lokhttp3/internal/ws/WebSocketReader$FrameCallback;, sources=[Unknown source 
file], original message=UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dex.DexException: Multiple dex files define 
Lokhttp3/internal/ws/WebSocketReader$FrameCallback;
at com.android.dx.merge.DexMerger.readSortableTypes(DexMerger.java:660)
at com.android.dx.merge.DexMerger.getSortedTypes(DexMerger.java:615)
at com.android.dx.merge.DexMerger.mergeClassDefs(DexMerger.java:597)
at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:170)
at com.android.dx.merge.DexMerger.merge(DexMerger.java:197)
at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:503)
at com.android.dx.command.dexer.Main.runMonoDex(Main.java:333)
at com.android.dx.command.dexer.Main.runDx(Main.java:288)
at com.android.dx.command.dexer.Main.main(Main.java:244)
at com.android.dx.command.Main.main(Main.java:95)
, tool name=Optional.of(Dex)}

任何人都可以指导我关于我在集成 peekaboo 时在我的应用程序完美运行之前我实际上犯了错误的问题然后它在 build.and 上给出了这个错误这是我的项目 build.gradle 文件。

/*
   Licensed to the Apache Software Foundation (ASF) under one
   or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
   regarding copyright ownership.  The ASF licenses this file
   to you under the Apache License, Version 2.0 (the
   "License"); you may not use this file except in compliance
   with the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   KIND, either express or implied.  See the License for the
   specific language governing permissions and limitations
   under the License.
   */

    apply plugin: 'com.android.application'

    buildscript {
    repositories {
    mavenCentral()
    jcenter()
    }

    // Switch the Android Gradle plugin version requirement depending on the
   // installed version of Gradle. This dependency is documented at
   // http://tools.android.com/tech-docs/new-build-system/version- 
   compatibility
  // and https://issues.apache.org/jira/browse/CB-8143
  dependencies {
    classpath 'com.android.tools.build:gradle:2.3.3'
}
}

// Allow plugins to declare Maven dependencies via build-extras.gradle.
allprojects {
repositories {
    mavenCentral();
    jcenter()
}
}

task wrapper(type: Wrapper) {
  gradleVersion = '3.3'
}

// Configuration properties. Set these via environment variables, build- 
extras.gradle, or gradle.properties.
// Refer to: 
http://www.gradle.org/docs/current/userguide/tutorial_this_and_that.html
ext {
 apply from: 'CordovaLib/cordova.gradle'
// The value for android.compileSdkVersion.
if (!project.hasProperty('cdvCompileSdkVersion')) {
    cdvCompileSdkVersion = null;
}
// The value for android.buildToolsVersion.
if (!project.hasProperty('cdvBuildToolsVersion')) {
    cdvBuildToolsVersion = null;
}
// Sets the versionCode to the given value.
if (!project.hasProperty('cdvVersionCode')) {
    cdvVersionCode = null
}
// Sets the minSdkVersion to the given value.
if (!project.hasProperty('cdvMinSdkVersion')) {
    cdvMinSdkVersion = null
}
// Whether to build architecture-specific APKs.
if (!project.hasProperty('cdvBuildMultipleApks')) {
    cdvBuildMultipleApks = null
}
// .properties files to use for release signing.
if (!project.hasProperty('cdvReleaseSigningPropertiesFile')) {
    cdvReleaseSigningPropertiesFile = null
}
// .properties files to use for debug signing.
if (!project.hasProperty('cdvDebugSigningPropertiesFile')) {
    cdvDebugSigningPropertiesFile = null
}
// Set by build.js script.
if (!project.hasProperty('cdvBuildArch')) {
    cdvBuildArch = null
}

// Plugin gradle extensions can append to this to have code run at the end.
cdvPluginPostBuildExtras = []
}

// PLUGIN GRADLE EXTENSIONS START
apply from: "peekaboo/allied-peekaboo.gradle"
// PLUGIN GRADLE EXTENSIONS END

 def hasBuildExtras = file('build-extras.gradle').exists()
 if (hasBuildExtras) {
  apply from: 'build-extras.gradle'
 }

 // Set property defaults after extension .gradle files.
 if (ext.cdvCompileSdkVersion == null) {
  ext.cdvCompileSdkVersion = privateHelpers.getProjectTarget()
 }
 if (ext.cdvBuildToolsVersion == null) {
  ext.cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools()
 }
 if (ext.cdvDebugSigningPropertiesFile == null && file('debug- 
 signing.properties').exists()) {
  ext.cdvDebugSigningPropertiesFile = 'debug-signing.properties'
 }
 if (ext.cdvReleaseSigningPropertiesFile == null && file('release- 
 signing.properties').exists()) {
  ext.cdvReleaseSigningPropertiesFile = 'release-signing.properties'
 }

 // Cast to appropriate types.
 ext.cdvBuildMultipleApks = cdvBuildMultipleApks == null ? false : 
 cdvBuildMultipleApks.toBoolean();
 ext.cdvMinSdkVersion = cdvMinSdkVersion == null ? null : Integer.parseInt('' 
 + 
 cdvMinSdkVersion)
 ext.cdvVersionCode = cdvVersionCode == null ? null : Integer.parseInt('' + 
 cdvVersionCode)

 def computeBuildTargetName(debugBuild) {
 def ret = 'assemble'
 if (cdvBuildMultipleApks && cdvBuildArch) {
    def arch = cdvBuildArch == 'arm' ? 'armv7' : cdvBuildArch
    ret += '' + arch.toUpperCase().charAt(0) + arch.substring(1);
 }
 return ret + (debugBuild ? 'Debug' : 'Release')
}

// Make cdvBuild a task that depends on the debug/arch-sepecific task.
task cdvBuildDebug
cdvBuildDebug.dependsOn {
return computeBuildTargetName(true)
}

task cdvBuildRelease
cdvBuildRelease.dependsOn {
return computeBuildTargetName(false)
}

task cdvPrintProps << {
println('cdvCompileSdkVersion=' + cdvCompileSdkVersion)
println('cdvBuildToolsVersion=' + cdvBuildToolsVersion)
println('cdvVersionCode=' + cdvVersionCode)
println('cdvMinSdkVersion=' + cdvMinSdkVersion)
println('cdvBuildMultipleApks=' + cdvBuildMultipleApks)
println('cdvReleaseSigningPropertiesFile=' + cdvReleaseSigningPropertiesFile)
println('cdvDebugSigningPropertiesFile=' + cdvDebugSigningPropertiesFile)
println('cdvBuildArch=' + cdvBuildArch)
println('computedVersionCode=' + android.defaultConfig.versionCode)
android.productFlavors.each { flavor ->
    println('computed' + flavor.name.capitalize() + 'VersionCode=' + 
flavor.versionCode)
}
}

android {
sourceSets {
    main {
        manifest.srcFile 'AndroidManifest.xml'
        java.srcDirs = ['src']
        resources.srcDirs = ['src']
        aidl.srcDirs = ['src']
        renderscript.srcDirs = ['src']
        res.srcDirs = ['res']
        assets.srcDirs = ['assets']
        jniLibs.srcDirs = ['libs']
     }
     }

defaultConfig {
    versionCode cdvVersionCode ?: new BigInteger("" + 
    privateHelpers.extractIntFromManifest("versionCode"))
    applicationId privateHelpers.extractStringFromManifest("package")

    if (cdvMinSdkVersion != null) {
        minSdkVersion cdvMinSdkVersion
    }
}

lintOptions {
  abortOnError false;
}

compileSdkVersion cdvCompileSdkVersion
buildToolsVersion cdvBuildToolsVersion

if (Boolean.valueOf(cdvBuildMultipleApks)) {
    productFlavors {
        armv7 {
            versionCode defaultConfig.versionCode*10 + 2
            ndk {
                abiFilters "armeabi-v7a", ""
            }
        }
        x86 {
            versionCode defaultConfig.versionCode*10 + 4
            ndk {
                abiFilters "x86", ""
            }
        }
        all {
            ndk {
                abiFilters "all", ""
            }
        }
    }
}
/*

ELSE NOTHING! DON'T MESS WITH THE VERSION CODE IF YOU DON'T HAVE TO!

else if (!cdvVersionCode) {
  def minSdkVersion = cdvMinSdkVersion ?: 
privateHelpers.extractIntFromManifest("minSdkVersion")
  // Vary versionCode by the two most common API levels:
  // 14 is ICS, which is the lowest API level for many apps.
  // 20 is Lollipop, which is the lowest API level for the updatable system 
webview.
  if (minSdkVersion >= 20) {
    defaultConfig.versionCode += 9
  } else if (minSdkVersion >= 14) {
    defaultConfig.versionCode += 8
  }
}
*/

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_7
    targetCompatibility JavaVersion.VERSION_1_7
}

if (cdvReleaseSigningPropertiesFile) {
    signingConfigs {
        release {
            // These must be set or Gradle will complain (even if they are 
            overridden).
            keyAlias = ""
            keyPassword = "__unset" // And these must be set to non-empty in 
           order to have the signing step added to the task graph.
            storeFile = null
            storePassword = "__unset"
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 
           'proguard-rules.pro'
        }
    }
    addSigningProps(cdvReleaseSigningPropertiesFile, signingConfigs.release)
}
if (cdvDebugSigningPropertiesFile) {
    addSigningProps(cdvDebugSigningPropertiesFile, signingConfigs.debug)
}
}

dependencies {
compile fileTree(include: '*.jar', dir: 'libs')
// SUB-PROJECT DEPENDENCIES START
debugCompile project(path: 'CordovaLib', configuration: 'debug')
releaseCompile project(path: 'CordovaLib', configuration: 'release')
// SUB-PROJECT DEPENDENCIES END
compile 'com.squareup.okhttp3:okhttp:3.7.0'
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:design:25.3.1'
}

def promptForReleaseKeyPassword() {
if (!cdvReleaseSigningPropertiesFile) {
    return;
}
if ('__unset'.equals(android.signingConfigs.release.storePassword)) {
    android.signingConfigs.release.storePassword = 
privateHelpers.promptForPassword('Enter key store password: ')
}
if ('__unset'.equals(android.signingConfigs.release.keyPassword)) {
    android.signingConfigs.release.keyPassword = 
privateHelpers.promptForPassword('Enter key password: ');
}
}

gradle.taskGraph.whenReady { taskGraph ->
taskGraph.getAllTasks().each() { task ->
    if (task.name == 'validateReleaseSigning' || task.name == 
'validateSigningRelease') {
        promptForReleaseKeyPassword()
    }
}
}

def addSigningProps(propsFilePath, signingConfig) {
def propsFile = file(propsFilePath)
def props = new Properties()
propsFile.withReader { reader ->
    props.load(reader)
}

def storeFile = new File(props.get('key.store') ?: 
privateHelpers.ensureValueExists(propsFilePath, props, 'storeFile'))
if (!storeFile.isAbsolute()) {
    storeFile = RelativePath.parse(true, 
storeFile.toString()).getFile(propsFile.getParentFile())
}
if (!storeFile.exists()) {
    throw new FileNotFoundException('Keystore file does not exist: ' + 
storeFile.getAbsolutePath())
}
signingConfig.keyAlias = props.get('key.alias') ?: 
privateHelpers.ensureValueExists(propsFilePath, props, 'keyAlias')
signingConfig.keyPassword = props.get('keyPassword', 
props.get('key.alias.password', signingConfig.keyPassword))
signingConfig.storeFile = storeFile
signingConfig.storePassword = props.get('storePassword', 
props.get('key.store.password', signingConfig.storePassword))
def storeType = props.get('storeType', props.get('key.store.type', ''))
if (!storeType) {
    def filename = storeFile.getName().toLowerCase();
    if (filename.endsWith('.p12') || filename.endsWith('.pfx')) {
        storeType = 'pkcs12'
    } else {
        storeType = signingConfig.storeType // "jks"
    }
}
signingConfig.storeType = storeType
}

for (def func : cdvPluginPostBuildExtras) {
func()
}

// This can be defined within build-extras.gradle as:
//     ext.postBuildExtras = { ... code here ... }
if (hasProperty('postBuildExtras')) {
postBuildExtras()
}

尝试从项目文件夹中删除 .gradle 文件夹和 .idea 文件夹,然后重建项目

我对您在此处提到的 peekaboo 库进行了快速研究,但找不到任何公开可用的信息,也许这是您的专有库。

但是,从报错信息来看,是因为你的类 from okhttp3 library 不止一处。如果你想使用你的 peekaboo 模块中的那个,那么你可以在你的 dependencies 闭包中删除这一行。

compile 'com.squareup.okhttp3:okhttp:3.7.0'  

或如下修改,将okhttpcom.squarup

中排除
compile 'com.squareup.okhttp3:okhttp:3.7.0' {
    exclude module: "okhttp"
}

而且,您始终可以使用下面的 gradle 命令来分析您的依赖关系树。

./gradlew -q dependencies

尝试找到你的 okhttp 模块存在的位置并排除其中一个,这样你就可以在 Dex 合并时避免 Multiple dex files definition 的错误。