【问题标题】:Manifest mergeing - Android studio 0.8.1 upgrade build error: property 'manifestFile' does not exist清单合并 - Android Studio 0.8.1 升级构建错误:属性“清单文件”不存在
【发布时间】:2014-07-02 16:10:37
【问题描述】:

我刚刚升级到 Android Studio 0.8.1 并升级了构建工具等。从 Android Studio 0.6

然后我得到这个构建错误:

发现任务配置有问题 ':processDevelopmentDebugResources'。

文件'C:\ProjectFolder\build\manifests\DevelopmentDebug\Development\debug\AndroidManifest.xml' 为属性“manifestFile”指定的不存在。

但我不知道问题出在哪里。 build 下的 manifests 文件夹不存在。
我怀疑这与我的代码的最后一部分有关,它替换了清单文件中的值。在构建工具更改列表中更改了有关“清单合并中的修复”的内容,但我不知道这是否相关。但话又说回来 - 该文件夹不存在,此代码应该更改其中的一些文件。

有什么线索吗?

编辑 1: 我只是试图将“variant.processManifest.doLast”部分注释掉并且它可以工作,所以问题出在这段代码上。 (为什么我以前没有尝试过。。)
但是在上一个版本中导致此代码失败的变化是什么?它在升级之前工作。

编辑 2: 请参阅 ianhanniballake 的回答下的 cmets。

这是我的 build.gradle 文件:

buildscript {
    repositories {
        mavenCentral()
        maven { url 'http://download.crashlytics.com/maven' }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.12.+'
        classpath 'com.crashlytics.tools.gradle:crashlytics-gradle:1.+'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.2'
    }
}

repositories {
    mavenCentral()
    maven { url 'http://download.crashlytics.com/maven' }
}

apply plugin: 'com.android.application'
apply plugin: 'crashlytics'
apply plugin: 'android-apt'

dependencies {
    compile 'com.crashlytics.android:crashlytics:1.+'
    compile fileTree(dir: 'libs', include: '*.jar')

    apt "org.androidannotations:androidannotations:3.0.1"
    compile "org.androidannotations:androidannotations-api:3.0.1"
}

apt {
    arguments {
        resourcePackageName "dk.packagename"
        androidManifestFile variant.processResources.manifestFile
    }
}

android {
    packagingOptions { //Fix: http://stackoverflow.com/a/20675331/860488
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'
    }

    compileSdkVersion 10
    buildToolsVersion "20.0"

    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 10
        buildConfigField "int", "appId", "2"
    }

    lintOptions {
        checkReleaseBuilds false
    }

    signingConfigs {
        //Use terminal command: gradle assembleKonnektRelease
        releaseKonnekt {

        }
    }

    productFlavors{
        def konnektSigningConfig = signingConfigs.releaseKonnekt

        Development {
            applicationId "dk.packagename"
            versionCode 1
            versionName "1.0.0"
            buildConfigField "int", "appId", "2"
        }
    }

    buildTypes {
        testflight.initWith(buildTypes.debug)
        debug {
            applicationIdSuffix ".debug"
        }

        testflight {
            applicationIdSuffix ".test"
        }

        release {
        }
    }

    // Override Data in Manifest
    android.applicationVariants.all { variant ->
        variant.processManifest.doLast {
            copy {
                // *** SET COPY PATHS ***
                try {
                    from("${buildDir}/manifests") {
                        //println "from: ${buildDir}/manifests"
                        include "${variant.dirName}/AndroidManifest.xml"
                        //println "included: ${variant.dirName}/AndroidManifest.xml"
                    }
                } catch (e) {
                    println "error: " + e
                }

                into("${buildDir}/manifests/${variant.name}")

                def variantName = variant.name.toString()
                def appName = "empty"
                def facebookId = "empty"

                // *** SET APP NAME ***
                if (variantName.contains("Development")) {
                    appName = "Development"
                } else if (variantName.contains("Konnekt")) {
                    appName = "Konnekt"
                    facebookId = "**"
                } 

                if(variantName.contains("Debug")){
                    appName = appName + " debug"
                } else if(variantName.contains("Test")){
                    appName = appName + " test"
                }

                // *** REPLACE LINES IN MANIFEST ***
                filter {
                    String line -> line.replaceAll("<application android:allowBackup=\"true\" android:icon=\"@drawable/ic_launcher\" android:label=\"todo\" android:name=\"dk.packagename.App\">", // implicit "." is replaced with: "dk.packagename."
                                                    "<application android:allowBackup=\"true\" android:icon=\"@drawable/ic_launcher\" android:label=\"" + appName + "\" android:name=\"dk.packagename.App\">");
                }
                filter {
                    String line -> line.replaceAll("<activity android:label=\"todo\" android:name=\"dk.packagename.SplashActivity\">",
                                                    "<activity android:label=\"" + appName + "\" android:name=\"dk.packagename.SplashActivity\">");
                }
                filter{
                    String line -> line.replaceAll("<meta-data android:name=\"com.facebook.sdk.ApplicationId\" android:value=\"\"/>",
                                                    "<meta-data android:name=\"com.facebook.sdk.ApplicationId\" android:value=\"" + facebookId + "\"/>")
                }
            }
        }

        // *** SET PATH TO NEW MANIFEST ***
        variant.processResources.manifestFile = file("${buildDir}/manifests/${variant.name}/${variant.dirName}/AndroidManifest.xml")
        //println "newManifest: ${buildDir}/manifests/${variant.name}/${variant.dirName}/AndroidManifest.xml"
    }
}

【问题讨论】:

  • 当您可以使用已经可用于构建变体的工具本机执行额外的清单处理时,您为什么还要进行额外的清单处理?
  • 你将如何处理我对构建变体所做的事情?动态应用程序标签,在 Activity 上设置标签并设置元数据? (查看我的编辑)

标签: android android-studio android-manifest android-gradle-plugin build.gradle


【解决方案1】:

这很可能是因为new manifest merging 成为默认值。新清单合并的一个好处是您不必使用这种方法 - 相反,您可以定义自定义占位符并将它们插入到合并过程中:

android {
    defaultConfig {
        manifestPlaceholders = [ activityLabel:"defaultName"]
    }
    productFlavors {
        free {
        }
        pro {
            manifestPlaceholders = [ activityLabel:"proName" ]
        }
    }

将替换以下声明中的占位符:

<activity android:name=".MainActivity" android:label="${activityLabel}" >

注意:您还可以将多个占位符组合在一起,例如android:label="${appName}${appType}",以适当地分割字符串并减少重复输入相同的信息。

【讨论】:

  • 看起来不错。但是如何向 manifestPlaceholders 添加多个值?我找不到任何语法,但我想它可能是这样的:manifestPlaceholders = [ activityLabel:"defaultName", label2:"value"]
  • 为 manifestPlaceholders 设置多个值的流行解决方案有效。但是${appName}${appType} 不起作用 - 只有第一个占位符是 renderet,它导致:“我的应用程序名称 ${appType}”。当我从 buildTypes 设置 manifestPlaceholders 时,它会被忽略。知道如何解决这些问题吗?
【解决方案2】:

你的问题出在:

from("${buildDir}/manifests")

此文件已移至$buildDir/intermediates/manifests/ 下。由于您的副本已经到位(似乎),所以什么都没有发生。

然后进程资源任务找不到你修改的文件,它不喜欢它。

您可以更新路径,也可以使用新的清单合并以更简单的方式完成您尝试做的所有事情。

文档在这里:http://tools.android.com/tech-docs/new-build-system/user-guide/manifest-merger

【讨论】:

    猜你喜欢
    • 2017-06-06
    • 1970-01-01
    • 1970-01-01
    • 2019-03-25
    • 1970-01-01
    • 2018-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多