Gradle 将插件升级到 3.0.0 时出现构建错误 (manifestOutputFile)

Gradle build error (manifestOutputFile) when upgrading plugin to 3.0.0

将 Gradle 插件版本升级到 3.0.0 (classpath "com.android.tools.build:gradle:3.0.0") 后,如果我尝试清理或构建项目,我会收到此错误:

A problem occurred configuring project ':app'.
> Manifest Tasks does not support the manifestOutputFile property any 
more, please use the manifestOutputDirectory instead.
  For more information, please check 
https://developer.android.com/studio/build/gradle-plugin-3-0-0-
migration.html

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

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

我没有在任何 gradle 文件中的任何地方使用 manifestOutputFile。使用 --debug--stacktrace 标志对我没有任何帮助。我猜这个问题出现在我的一个依赖项中,但我不知道。另外,我在很多 类 中使用 Kotlin;我不确定这是否重要。有谁知道是否有办法查看哪个库引发此错误?或者当 build.gradle 文件甚至没有引用 manifestOutputFile 时,有人对这个问题有任何建议或见解吗?

这是 build.gradle 文件的大部分内容:

buildscript {
    repositories {
        jcenter()
        mavenCentral()
        maven { url 'https://maven.fabric.io/public' }
        maven { url 'https://plugins.gradle.org/m2/' }
        maven { url 'https://maven.google.com'}
    }

    dependencies {
        classpath 'io.fabric.tools:gradle:1.24.4'
        classpath 'me.tatarka:gradle-retrolambda:3.7.0'
        classpath 'com.dicedmelon.gradle:jacoco-android:0.1.2'
        classpath 'com.github.ben-manes:gradle-versions-plugin:0.17.0'
        classpath 'gradle.plugin.com.nobleworks_software.icon-overlay:icon-overlay-plugin:1.2.3'
    }
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: 'me.tatarka.retrolambda'
apply plugin: 'io.fabric'
apply plugin: 'checkstyle'
apply plugin: 'findbugs'
apply plugin: 'jacoco'
apply plugin: 'jacoco-android'
apply plugin: 'com.github.ben-manes.versions'
apply plugin: 'com.nobleworks_software.icon-overlay'


repositories {
    jcenter()
    maven { url 'https://maven.fabric.io/public' }
    flatDir {
        dirs 'libs'
    }
}

ext {
    libsSrcDir = new File('${projectDir}/libs')
}

String gpsPropertyName = 'gps'
String gpsPropertyValueAlpha = 'alpha'
String gpsPropertyValueBeta = 'beta'
boolean tangoBuild = false
String tangoPropertyName = 'tango'
String alphaBuildEnding = '20'
String betaBuildEnding = '10'
String productionBuildEnding = '00'

def isBuildForGPS = { ->
    return project.hasProperty(gpsPropertyName)
}

def isTangoBuild = { ->
    return project.hasProperty(tangoPropertyName)
}

def getBranchName = { ->
    try {
        def branchOut = new ByteArrayOutputStream()

        exec {
            commandLine 'git', 'symbolic-ref', '--short', 'HEAD'
            standardOutput = branchOut
        }

        return branchOut.toString().trim()
    }
    catch (ignored) {
        return 'master'
    }
}

def getVersionCode = { ->
    try {
        def stdout = new ByteArrayOutputStream()

        exec {
            commandLine 'git', 'rev-list', '--count', 'HEAD'
            standardOutput = stdout
        }

        // Make the Tango version use '50' as the least sig offset
        int tangoOffset = 0
        if (tangoBuild) {
            tangoOffset = 50
        }
        if (isBuildForGPS()) {
            String channel = project.findProperty(gpsPropertyName)
            if (gpsPropertyValueAlpha == channel) {
                return Integer.parseInt(stdout.toString().trim() + alphaBuildEnding) + tangoOffset
            } else if (gpsPropertyValueBeta == channel) {
                return Integer.parseInt(stdout.toString().trim() + betaBuildEnding) + tangoOffset
            }
        }

        return Integer.parseInt(stdout.toString().trim() + productionBuildEnding) + tangoOffset
    }
    catch (ignored) {
        return -1
    }
}

def getVersionName = { ->
    try {
        if (isBuildForGPS()) {
            def tag = getLastTaggedVersion()

            String channel = project.findProperty(gpsPropertyName)
            if (gpsPropertyValueAlpha == channel) {
                tag = tag + '-a'
            } else if (gpsPropertyValueBeta == channel) {
                tag = tag + '-b'
            }

            return tag
        } else {
            return getBranchName()
        }
    }
    catch (ignored) {
        return 'X.X.X'
    }
}

android {
    compileSdkVersion 26
    buildToolsVersion '26.0.2'

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    dexOptions {
        javaMaxHeapSize "4g"
    }

    dataBinding {
        enabled = true
    }

    defaultConfig {
        versionCode getVersionCode()
        versionName getVersionName()
        applicationId getApplicationId()
        minSdkVersion 16
        targetSdkVersion 26
        multiDexEnabled = true
        multiDexKeepFile file('multidex_keep_file.txt')
        vectorDrawables.useSupportLibrary = true
        testInstrumentationRunner "com.demoapp.demoapp.WayTestRunner"
        renderscriptTargetApi 16
        renderscriptSupportModeEnabled true

        String branchName = getBranchName().toUpperCase()
        String iconOverlayText = branchName.toLowerCase()

        buildConfigField "String", "LAST_TAGGED_VERSION", "\"${getLastTaggedVersion()}\""

        if (branchName == 'DEV') {
            iconOverlayText = 'ALPHA'
        } else if (branchName.startsWith('RELEASE')) {
            iconOverlayText = 'BETA'
        }

        if (!isBuildForGPS()) {
            iconOverlay {
                enabled = true
                fontSize = 8
                textColor = [255, 255, 255, 255]
                verticalLinePadding = 2
                backgroundOverlayColor = [0, 0, 0, 180]
                text = { "$iconOverlayText" }
            }
        }

        configurations.all {
            resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'
        }

        javaCompileOptions {
            annotationProcessorOptions {
                arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
            }
        }
    }

    flavorDimensions("store", "3d_enabled")
    productFlavors {
        demoapp {
            dimension = "store"
            applicationId getApplicationId()
            // Dupe required because SearchRecentSuggestionsProvider has no available context in its constructor
            buildConfigField "String", "SEARCH_RECENT_AUTHORITY", "\"${applicationId}.WFSearchRecentSuggestionsProvider\""
            // And one for the manifest
            resValue "string", "SEARCH_RECENT_AUTHORITY", "${applicationId}.WFSearchRecentSuggestionsProvider"

            // These need to be defined as string resources so they can be registered in the manifest.
            // However in order to access them in tests it's convenient to have them also defined in BuildConfig
            String deepLinkScheme = "demoappapp"
            resValue "string", "EXPLICIT_DEEP_LINK_SCHEME1", deepLinkScheme
            resValue "string", "EXPLICIT_DEEP_LINK_SCHEME2", deepLinkScheme
            buildConfigField "String", "EXPLICIT_DEEP_LINK_SCHEME1", "\"${deepLinkScheme}\""
            buildConfigField "String", "EXPLICIT_DEEP_LINK_SCHEME2", "\"${deepLinkScheme}\""

            if (getBranchName().toUpperCase() == 'MASTER') {
                manifestPlaceholders = [
                        appIcon     : "@mipmap/ic_launcher",
                        appRoundIcon: "@mipmap/ic_launcher_round"
                ]
            } else {
                manifestPlaceholders = [
                        appIcon     : "@mipmap/ic_launcher_dev",
                        appRoundIcon: "@mipmap/ic_launcher_dev_round"
                ]
            }
        }

        demoappflavor {
            dimension = "store"
            applicationId getDemoappflavorApplicationId()
            // Dupe required because SearchRecentSuggestionsProvider has no available context in its constructor
            buildConfigField "String", "SEARCH_RECENT_AUTHORITY", "\"${applicationId}.WFSearchRecentSuggestionsProvider\""
            // And one for the manifest
            resValue "string", "SEARCH_RECENT_AUTHORITY", "${applicationId}.WFSearchRecentSuggestionsProvider"

            // These need to be defined as string resources so they can be registered in the manifest.
            // However in order to access them in tests it's convenient to have them also defined in BuildConfig
            String deepLinkScheme1 = "theapp"
            String deepLinkScheme2 = "demoappflavorapp"
            resValue "string", "EXPLICIT_DEEP_LINK_SCHEME1", deepLinkScheme1
            resValue "string", "EXPLICIT_DEEP_LINK_SCHEME2", deepLinkScheme2
            buildConfigField "String", "EXPLICIT_DEEP_LINK_SCHEME1", "\"${deepLinkScheme1}\""
            buildConfigField "String", "EXPLICIT_DEEP_LINK_SCHEME2", "\"${deepLinkScheme2}\""

            manifestPlaceholders = [
                    appIcon     : "@mipmap/ic_launcher",
                    appRoundIcon: "@mipmap/ic_launcher_round"
            ]
        }
    }

    android.variantFilter { variant ->
        def store = variant.getFlavors().get(0).name
        def tango_enabled = variant.getFlavors().get(1).name

        // Disable building the tango dimension
        if ((store == 'demoappflavor' || !isTangoBuild()) && tango_enabled == "tangoEnabled") {
            variant.setIgnore(true)
        }
    }

    buildTypes {
        release {
            // Commented out to stop a production build crash with OKIO
            //minifyEnabled true
            // Commented out due to Gradle 2.2.0 issue
            //shrinkResources true
            ext.enableCrashlytics = true
            apply plugin: 'signing'
            signingConfig signingConfigs.release
            ext.betaDistributionReleaseNotesFilePath = './release-notes.txt'
            ext.betaDistributionGroupAliases = 'android-nightly'
            buildConfigField 'boolean', 'OVERRIDE_MIN_VERSION', isBuildForGPS() ? 'false' : 'true'
            buildConfigField 'boolean', 'ENABLE_APPSEE', isBuildForGPS() ? 'true' : 'false'
        }

        debug {
            // TODO: Uncomment this out to enable code coverage
//            testCoverageEnabled true
            buildConfigField 'boolean', 'OVERRIDE_MIN_VERSION', isBuildForGPS() ? 'false' : 'true'
            buildConfigField 'boolean', 'ENABLE_APPSEE', isBuildForGPS() ? 'true' : 'false'
        }

        configurations.all {
            resolutionStrategy {
                force 'com.google.code.findbugs:jsr305:1.3.9'
                force 'com.google.guava:guava:21.0'
                force "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
                force 'com.google.code.gson:gson:2.8.2'
            }
        }
    }

    packagingOptions {
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'
        exclude 'bin/AndroidManifest.xml'
        exclude 'bin/jarlist.cache'
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'

        return 0
    }

    testOptions {
        // Disable animations for UI testing
        animationsDisabled = true
        unitTests.returnDefaultValues = true
        unitTests.all {
            jacoco {
                includeNoLocationClasses = true
            }
        }
    }

    sourceSets {
        androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
    }
}

configurations {
    demoappTangoEnabledCompile
}

allprojects {
    repositories {
        jcenter()
        maven { url 'https://jitpack.io' }
        maven { url "https://clojars.org/repo/" }
    }
}

ext.daggerVersion = '2.11'
ext.playServicesVersion = '11.6.2'
ext.supportLibsVersion = '27.0.1'
ext.robolectricVersion = '3.3.2'
ext.frescoVersion = '1.5.0'
ext.leakCanaryVersion = '1.5.4'
ext.roomVersion ='1.0.0'
ext.butterKnifeVersion ='8.7.0'
ext.espressoVersion ='3.0.1'
ext.gsonVersion ='2.8.2'
ext.mockitoVersion ='2.9.0'
ext.dexmakerVersion ='1.2'
ext.icepickVersion ='3.2.0'
ext.multidexVersion ='1.0.2'

dependencies {
    // Compile Project
    compile(project(':models'))

    // Compile
    compile('com.crashlytics.sdk.android:crashlytics:2.7.1@aar') {
        transitive = true
    }
    // GOOGLE LIBS
    compile "com.android.support:design:${supportLibsVersion}"
    compile "com.android.support:recyclerview-v7:${supportLibsVersion}"
    compile "com.android.support:cardview-v7:${supportLibsVersion}"
    compile "com.android.support:support-v4:${supportLibsVersion}"
    compile "com.android.support:support-v13:${supportLibsVersion}"
    compile "com.android.support:percent:${supportLibsVersion}"
    compile "com.android.support:support-annotations:${supportLibsVersion}"
    compile "com.android.support:appcompat-v7:${supportLibsVersion}"
    compile "com.android.support:multidex:${multidexVersion}"
    compile "com.google.code.gson:gson:${gsonVersion}"

    // FIREBASE AND PLAY SERVICES
    compile "com.google.firebase:firebase-messaging:${playServicesVersion}"
    compile "com.google.firebase:firebase-appindexing:${playServicesVersion}"
    //noinspection GradleDependency
    compile "com.google.android.gms:play-services-analytics:${playServicesVersion}"
    //noinspection GradleDependency
    compile "com.google.android.gms:play-services-auth:${playServicesVersion}"
    //noinspection GradleDependency
    compile "com.google.android.gms:play-services-wallet:${playServicesVersion}"

    // FLOW LAYOUT FOR CHIPS
    compile 'org.apmem.tools:layouts:1.10@aar'
    // RxJava and related
    compile 'io.reactivex.rxjava2:rxjava:2.1.7'
    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
    compile project(':FloatingSearchView')

    // RxJava support for Room
    compile 'android.arch.persistence.room:rxjava2:1.0.0'
// Testing support
    androidTestCompile 'android.arch.core:core-testing:1.1.0'
    // Dagger
    compile "com.google.dagger:dagger:${daggerVersion}"
    compile "com.google.dagger:dagger-android-support:${daggerVersion}"
    kapt "com.google.dagger:dagger-compiler:${daggerVersion}"
    kapt "com.google.dagger:dagger-android-processor:${daggerVersion}"

    compile ("com.facebook.fresco:imagepipeline-okhttp3:${frescoVersion}") {
        exclude group: 'com.squareup.okhttp3', module: 'okhttp'
    }

    compile "com.jakewharton:butterknife:${butterKnifeVersion}"
    kapt "com.jakewharton:butterknife-compiler:${butterKnifeVersion}"
    compile 'com.android.support.constraint:constraint-layout:1.1.0-beta4'
    compile 'com.appsee:appsee-android:2.3.4'

    compile 'commons-io:commons-io:2.5'

    compile "com.android.support.test:runner:1.0.1"

    // ESPRESSO
    androidTestCompile "com.android.support:support-v4:${supportLibsVersion}"
    androidTestCompile "com.android.support:support-annotations:${supportLibsVersion}"
    androidTestCompile "com.android.support:recyclerview-v7:${supportLibsVersion}"
    androidTestCompile "com.android.support:design:${supportLibsVersion}"
    androidTestCompile "com.android.support:recyclerview-v7:${supportLibsVersion}"
    androidTestCompile "com.android.support.test.espresso:espresso-core:${espressoVersion}"
    androidTestCompile "com.android.support.test.espresso:espresso-intents:${espressoVersion}"
    androidTestCompile "com.android.support.test.espresso:espresso-contrib:${espressoVersion}"
    androidTestCompile "com.android.support.test.espresso:espresso-web:${espressoVersion}"
    androidTestCompile "org.mockito:mockito-core:${mockitoVersion}"
    androidTestCompile "com.google.dexmaker:dexmaker:${dexmakerVersion}"
    androidTestCompile "com.google.dexmaker:dexmaker-mockito:${dexmakerVersion}"
    androidTestCompile "com.android.support:multidex:${multidexVersion}"
    androidTestCompile "org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}"
    androidTestCompile "org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}"
    androidTestCompile "com.google.code.gson:gson:${gsonVersion}"
    androidTestCompile('com.jakewharton.espresso:okhttp3-idling-resource:1.0.0') {
        //Using App Version Instead
        exclude group: 'com.squareup.okio', module: 'okio'
        exclude group: 'com.squareup.okhttp3', module: 'okhttp'
    }
    //WireMock
    androidTestCompile( project(":wiremock")) {
        //Using Android Version Instead
        exclude group: 'org.apache.httpcomponents', module: 'httpclient'

        exclude group: 'org.ow2.asm', module: 'asm'

        //Using Android Version Instead
        exclude group: 'org.json', module: 'json'
        exclude group: 'com.google.guava', module: 'guava'
    }

    androidTestCompile 'org.apache.httpcomponents:httpclient-android:4.3.5.1'
    testCompile 'junit:junit:4.12'
    testCompile "org.mockito:mockito-core:${mockitoVersion}"
    testCompile 'org.hamcrest:hamcrest-library:1.3'
    testCompile "org.robolectric:robolectric:${robolectricVersion}"
    testCompile "org.robolectric:shadows-multidex:${robolectricVersion}"
    testCompile "org.robolectric:shadows-support-v4:${robolectricVersion}"
    testCompile "com.google.code.gson:gson:${gsonVersion}"
    testCompile "com.google.dagger:dagger:${daggerVersion}"
    testCompile "com.android.support:multidex:${multidexVersion}"
    kaptTest "com.google.dagger:dagger-compiler:${daggerVersion}"
    // Kotlin mockito
    testCompile ("com.nhaarman:mockito-kotlin-kt1.1:1.5.0"){
        exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib'
        exclude group: 'org.jetbrains.kotlin', module: 'kotlin-reflect'
    }

    compile "frankiesardo:icepick:${icepickVersion}"
    provided "frankiesardo:icepick-processor:${icepickVersion}"

    compile "com.facebook.fresco:fresco:${frescoVersion}"
    compile "com.facebook.fresco:animated-gif:${frescoVersion}"
    // Canary
    debugCompile "com.squareup.leakcanary:leakcanary-android:${leakCanaryVersion}"
    releaseCompile "com.squareup.leakcanary:leakcanary-android-no-op:${leakCanaryVersion}"
    androidTestCompile "com.squareup.leakcanary:leakcanary-android-no-op:${leakCanaryVersion}"
    testCompile "com.squareup.leakcanary:leakcanary-android-no-op:${leakCanaryVersion}"
    compile 'com.prolificinteractive:material-calendarview:1.4.3'

    //Card IO
    compile 'io.card:android-sdk:5.5.1'
    compile 'com.facebook.rebound:rebound:0.3.8'

    //Chrome Web-View
    compile "com.android.support:customtabs:${supportLibsVersion}"
    def folder = new File('./brickkit-android/BrickKit/bricks/build.gradle')
    if (folder.exists()) {
        compile project(':bricks')
    } else {
        compile 'com.demoapp:brickkit-android:0.9.27'
    }

    // intellij annotations are included in kotlin, so this creates
    // a "java.util.zip.ZipException: duplicate entry" on its modules
    //compile 'com.intellij:annotations:12.0@jar'

    testCompile "com.google.dagger:dagger:${daggerVersion}"

    demoappTangoEnabledCompile project(':demoappView')
    compile ('com.perimeterx.sdk:msdk:1.1.0') {
        exclude group: 'com.squareup.okhttp3', module: 'okhttp'
    }

    // Kotlin support
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlinVersion"
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
    compile "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion"

    //Data binding
    kapt "com.android.databinding:compiler:$gradleVersion"
    compile 'nl.littlerobots.rxlint:rxlint:1.4'

    // Room
    compile "android.arch.persistence.room:runtime:${roomVersion}"
    kapt "android.arch.persistence.room:compiler:${roomVersion}"
    androidTestCompile "android.arch.persistence.room:testing:${roomVersion}"


    // Stetho
    compile 'com.facebook.stetho:stetho:1.5.0'
    compile 'com.facebook.stetho:stetho-js-rhino:1.4.2'

    compile 'com.siftscience:sift-android:0.9.10'
}

import groovy.json.JsonBuilder
task uploadapithingFiles << {
    // Get all the apithing files
    String apithingDir = "${project.rootDir}/models/src/main/java/com/demoapp/models/requests/apithing-files"
    FileTree files = fileTree(dir: apithingDir)

    // TreeMap of File names and File Data
    TreeMap<String, String> fileMap = new TreeMap<>()
    files.each { file ->
        Scanner input = new Scanner(file)
        String output = ""
        while (input.hasNext()) {
            output = output + input.nextLine()
        }
        input.close()
        fileMap.put(file.name.take(file.name.lastIndexOf('.')), output)
    }

    // Build request JSON
    def json = new JsonBuilder()
    json{
        payload {
            build_id getVersionCode()
            client_id 2
            version lastTaggedVersion
            is_production isBuildForGPS() ? 1 : 0
            queries fileMap.collect {
                [
                        "name": it.key,
                        "query": it.value
                ]
            }
        }
    }

    // Create POST Request
    def url = 'http://services.demoapp.com:8280/purest/performance/app_apithing'
    def post = new URL(url).openConnection()
    def message = json.toString()

    projects.logger.debug(message)

    post.setRequestMethod("POST")
    post.setRequestProperty("Content-Type", "application/json; charset=utf-8")
    post.setDoOutput(true)
    post.getOutputStream().write(message.getBytes("UTF-8"))

    def responseCode = post.getResponseCode()
    if(responseCode >= 200 && responseCode <= 299) {
        projects.logger.lifecycle("apithing upload successful.")
    } else {
        projects.logger.lifecycle("apithing Upload Failed with response: ${post.getResponseMessage()}")
        throw new GradleException("ERROR: Unable to upload apithing files. Server returned a response code: ${responseCode}")
    }
}

project.gradle.taskGraph.whenReady {
    ->
    project.tasks.findAll { it.name =~ /connected.+AndroidTest/ }.each {
        it.ignoreFailures = true
    }
}

def errorOutput(dir) {
    println "\n\n================OUTPUT REPORT=================\n\n"
    println "The file $dir does not exist\n "
    println "Check the current APK Path and Version "
    println "\n\n==============================================\n\n"
}

def executeUpload(dir, isUpload, key) {
    if (isUpload) {
        exec {
            commandLine 'curl', 'https://tok_gh6e7yrydkhgqyaz2fvx702y8m@api.appetize.io/v1/apps', '-F', "file=@$dir", '-F', 'platform=android'
        }
    } else {
        exec {
            commandLine 'curl', "https://tok_gh6e7yrydkhgqyaz2fvx702y8m@api.appetize.io/v1/apps/$key", '-F', "file=@$dir", '-F', 'platform=android'
        }
    }
}

apply plugin: 'com.google.gms.google-services'

jacocoAndroidUnitTestReport {
    excludes += ['**/R.class','**/R$*.class','**/*$ViewInjector*.*','**/*$ViewBinder*.*','**/BuildConfig.*','**/Manifest*.*','**/*$Lambda$*.*','**/*Module.*','**/*Dagger*.*','**/*MembersInjector*.*','**/*_Provide*Factory*.*','**/*_Factory*.*','**/*$*$*.*','**/test*/**','**/androidTest/**','**/databinding/**']
}

tasks.whenTaskAdded { task ->
    if (task.name == 'connecteddemoappDebugAndroidTest' || task.name == 'connecteddemoappflavorDebugAndroidTest') {
        task.doFirst() {
            exec {

                commandLine 'sh', 'get_android_wiremock.sh'
            }
        }

        task.doLast() {
            exec {
                commandLine 'sh', 'get_device_recordings.sh', 'wiremock_blacklist.txt'
            }
        }
    }
}

android.applicationVariants.all { variant ->
    task("checkstyle${variant.name.capitalize()}", type: Checkstyle) {
        configFile file("${project.rootDir}/config/quality/checkstyle/checkstyle.xml")
        configProperties.checkstyleSuppressionsPath = file("${project.rootDir}/config/quality/checkstyle/suppressions.xml").absolutePath
        source 'src'
        include '**/*.java'
        exclude '**/gen/**'
        exclude '**/models/generated/**'
        classpath = files() as FileCollection
        group = "verification"
    }
    check.dependsOn("checkstyle${variant.name.capitalize()}")
}

android.applicationVariants.all { variant ->
    task("findbugs${variant.name.capitalize()}", type: FindBugs) {
        ignoreFailures = false
        effort = "default"
        reportLevel = "medium"
        excludeFilter = new File("${project.rootDir}/config/quality/findbugs/findbugs-filter.xml")
        classes = files("${project.rootDir}/app/build/intermediates/classes")
        source = fileTree('src/main/java/')
        classpath = files()
        group = "verification"
        reports {
            xml.enabled = false
            html.enabled = true
            xml {
                destination "$project.buildDir/findbugs/findbugs-output.xml"
            }
            html {
                destination "$project.buildDir/findbugs/findbugs-output.html"
            }
        }

        dependsOn "compile${variant.name.capitalize()}JavaWithJavac"
    }
    check.dependsOn("findbugs${variant.name.capitalize()}")
}

android.applicationVariants.all { variant ->
    task("buildCheckTest${variant.name.capitalize()}", type: GradleBuild) {
        dependsOn "checkstyle${variant.name.capitalize()}"
        dependsOn "assemble${variant.name.capitalize()}"
        dependsOn "lint${variant.name.capitalize()}"
        dependsOn "findbugs${variant.name.capitalize()}"
        dependsOn "test${variant.name.capitalize()}UnitTest"
        dependsOn "jacocoTest${variant.name.capitalize()}UnitTestReport"
        mustRunAfter "clean"
    }
}

task buildReleaseTest(type: GradleBuild)

android.applicationVariants.all { variant ->
    if (variant.name.endsWith("Release")) {
        buildReleaseTest.dependsOn("buildCheckTest${variant.name.capitalize()}")
    }
}

android.applicationVariants.all {  v ->
    if (v.buildType.name == "release"){
        v.assemble.dependsOn("uploadapithingFiles")
    }
}

buildReleaseTest.mustRunAfter('clean')

task cleanBuildReleaseTest(type: GradleBuild)
cleanBuildReleaseTest.dependsOn('clean')
cleanBuildReleaseTest.dependsOn('buildReleaseTest')

哇,这么多插件。出现错误消息是因为其中一个依赖于在 3.x 中更改的 API(因此迁移 link)。您需要更新相应的插件。

根据下面第 3 步的 gradle dependencies 运行,我的猜测是 gradle.plugin.com.nobleworks_software.icon-overlay:icon-overlay-plugin。它显示 com.android.tools.build:gradle:2.2.3 -> 3.0.1 嵌套在

(如果您将 3.0.1 Android Gradle 插件添加到您的 build.gradle)

--stacktrace 应该也给了你调用 com.android.build.gradle.tasks.ManifestProcessorTask#getManifestOutputFile 的确切位置。如果没有,您仍然可以执行以下操作:


如果我有mvce,我会用这种方式回答这个问题。您有太多插件无法从头开始手动设置所有内容。此方法也适用于插件中的任何 Gradle buildscript 怪异。

  1. 在 AS/IDEA
    中关闭您的项目 注意:如果您的项目中有一个 buildSrc 也可以工作,则无需关闭并创建另一个。
  2. 使用 build.gradle 文件创建另一个项目(我们称之为 debugger)如下:

    • buildscript {} 的项目内容(但没有 buildscript 块!)

      repositories {
          jcenter()
          ...
      }
      dependencies {
          implementation ... // for each classpath ...
      }
      
    • 在根级别添加 plugins { id 'java' }

    • dependencies
    • 内添加implementation 'com.android.tools.build:gradle:3.0.1'
  3. 在 IDEA/Android Studio 中打开此项目
    (这将下载这些插件的所有源代码)
  4. 运行 gradlew --no-daemon -Dorg.gradle.debug=true --debug --stacktrace 来自终端
    (这将停止执行并等待,
    注意:Listening for transport dt_socket at address: 5005)
  5. 转到 debugger 项目中的 "Run/Debug configurations" 对话框
    • 使用 Gradle 日志中的参数创建 "Remote" 配置(绿色 +):
    • 使用确定/应用关闭对话框
  6. 跳转到class/filecom.android.build.gradle.tasks.ManifestProcessorTask里面gradle-core-3.0.1-sources.jar
  7. ManifestProcessorTask.getManifestOutputFile
  8. 的第 128 行放置一个断点
  9. 为了安全起见,对 gradle-core-3.0.1.jar 的反编译代码也重复上述两个步骤。 (行号可能不同)
  10. 运行 菜单 > 调试 "Remote"
  11. 断点命中时等待并庆祝,您会在 Debug 视图的 Stack 框架列表中看到谁调用了该方法。

看起来很吃力,但是你做了一次之后就非常简单和快速了。