【问题标题】:Replacing a string in AndroidManifest.xml for a buildvariant doesn't work for Gradle Android Plugin Version > 0.5.4将 AndroidManifest.xml 中的字符串替换为 buildvariant 不适用于 Gradle Android Plugin Version > 0.5.4
【发布时间】:2023-04-09 07:47:01
【问题描述】:

就在几周前,我有以下问题:How to replace a string for a buildvariant with gradle?

我自己也回答了这个问题。

到目前为止一切正常:我刚刚意识到我的复制任务不再工作了。我花了几个小时解决这个问题,直到我意识到它取决于 Gradle Android 插件版本:在 0.5.4 之前的一切都可以正常工作。对于更高版本,我不会进入我的复制任务。

这是控制台输出:

// gradle android plugin version: 0.5.6 and 0.5.5 --> copy tas doesn't work
:etscanner:prepareFlavor1Flavor1ReviewDependencies
:etscanner:compileFlavor1Flavor1ReviewAidl
:etscanner:generateFlavor1Flavor1ReviewBuildConfig
:etscanner:mergeFlavor1Flavor1ReviewAssets
:etscanner:compileFlavor1Flavor1ReviewRenderscript
:etscanner:mergeFlavor1Flavor1ReviewResources
:etscanner:processFlavor1Flavor1ReviewManifest
:etscanner:processFlavor1Flavor1ReviewResources
:etscanner:compileFlavor1Flavor1ReviewNote: Some input files use or override a d
eprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: <path>.DetailAdapter
.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

:etscanner:dexFlavor1Flavor1Review
:etscanner:processFlavor1Flavor1ReviewJavaRes UP-TO-DATE
:etscanner:validateFlavor1Flavor1Signing
:etscanner:packageFlavor1Flavor1Review
:etscanner:zipalignFlavor1Flavor1Review

// gradle android plugin version: 0.5.4 --> copy task work
:etscanner:prepareFlavor1Flavor1ReviewDependencies
:etscanner:compileFlavor1Flavor1ReviewAidl
:etscanner:generateFlavor1Flavor1ReviewBuildConfig
:etscanner:mergeFlavor1Flavor1ReviewAssets
:etscanner:compileFlavor1Flavor1ReviewRenderscript
:etscanner:mergeFlavor1Flavor1ReviewResources
:etscanner:processFlavor1Flavor1ReviewManifest
...hey you are in the copy task!
:etscanner:processFlavor1Flavor1ReviewResources
:etscanner:compileFlavor1Flavor1ReviewNote: Some input files use or override a d
eprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: <path>DetailAdapter
.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

:etscanner:dexFlavor1Flavor1Review
:etscanner:processFlavor1Flavor1ReviewJavaRes UP-TO-DATE
:etscanner:validateFlavor1Flavor1Signing
:etscanner:packageFlavor1Flavor1Review
:etscanner:zipalignFlavor1Flavor1Review
:etscanner:assembleFlavor1Flavor1Review

这真是一件奇怪的事情...... 有谁知道如何解决这个问题?

更新 1 2013-08-23

我的 build.gradle 文件:

buildscript {
    repositories {
        // maven central repo doesn't work with gradle android plugin version 0.5.+
        // error message is describe in this post:
        // https://plus.google.com/117954254390243608387/posts/RVBjoDMkLV5
        //mavenCentral()
        maven {
            url 'http://nexus/content/groups/public/'
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.5.4'
        // copy task doesn't work for following versions:
        //classpath 'com.android.tools.build:gradle:0.5.5'
        //classpath 'com.android.tools.build:gradle:0.5.6'
        //classpath 'com.android.tools.build:gradle:0.5.+'
    }
}

apply plugin: 'android'

dependencies {
    compile 'com.android.support:support-v4:13.0.+' // support lib
    //compile 'com.actionbarsherlock:actionbarsherlock:4.4.0@aar'
    compile project(':libraries:actionbarsherlock')
    compile project(':libraries:google-play-services_lib')
}

android {
    compileSdkVersion 17
    buildToolsVersion "17.0.0"

    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 17
        versionName = "2.3"
        versionCode = 4
    }

    // SIGN CONFIGS
    signingConfigs {
        flavor1 {
            storeFile file("keystore/myKeystore.keystore")
            storePassword = "store_password"
            keyAlias = "alias"
            keyPassword = "key_password"
        }
        flavor2 {
            storeFile file("keystore/myKeystore.keystore")
            storePassword = "store_password"
            keyAlias = "alias"
            keyPassword = "key_password"
        }
        debug {
            storeFile file("keystore/debug.keystore")
            storePassword = "android"
            keyAlias = "androiddebugkey"
            keyPassword = "android"
        }

    }

    // FLAVORS
    productFlavors {
        flavor1 {
            packageName 'myPackageName'
            signingConfig signingConfigs.flavor1
        }
        flavor2 {
            packageName 'myPackageName'
            signingConfig signingConfigs.flavor2
        }
    }

    // BUILDTYPES
    buildTypes {
        falvor1Review {
            versionNameSuffix = versionNameSuffixOfReviewVersion
            signingConfig signingConfigs.flavor1
        }
        flavor2Review {
            versionNameSuffix = versionNameSuffixOfReviewVersion
            signingConfig signingConfigs.flavor2
        }

        debug {
            packageNameSuffix ".debug"
            versionNameSuffix = versionNameSuffixOfReviewVersion
            signingConfig signingConfigs.debug
        }
    }

    // Override Data in Manifest
    android.applicationVariants.each { 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}")
                //println "into (neues Manifest): ${buildDir}/manifests/${variant.name}"

                // *** DEFINE VARS ***
                def brandVersion = variant.buildType.name
                def brandVersionString = brandVersion.toString()
                def appName = "empty"

                // *** SET APP NAME ***
                if (brandVersionString.contains("flavor1")) {
                    appName = "my app name for flavor 1"
                } else if (brandVersionString.contains("flavor2")) {
                    appName = "my app name for flavor 2"
                }

                println "...hey you are in the copy task"
                // *** REPLACE LINES IN MANIFEST ***
                // --- add appName
                filter {
                    String line ->
                        line.replaceAll("<application android:allowBackup=\"true\" android:icon=\"@drawable/ic_launcher\" android:label=\"todo\" android:theme=\"@style/AppTheme\">",
                                "<application android:allowBackup=\"true\" android:icon=\"@drawable/ic_launcher\" android:label=\"" + appName + "\" android:theme=\"@style/AppTheme\">");
                }
            }
        }

        // *** 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"
    }
}

更新 2 2013-08-23

昨天我在 AS 0.2.5 遇到了另一个奇怪的行为,它做了一些非常奇怪的构建: 正如你在我的过滤器中看到的,我之前在 Manifest 中的 appName 是“todo”:

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="todo"
    android:theme="@style/AppTheme">

当我进行构建时,应用程序中的 appName 是正确的。但在应用程序启动器和设置/应用程序中,“todo”显示为 appName。

在 AS 0.2.0 中构建项目后一切正常。

【问题讨论】:

  • 在不知道您的任务是如何创建和设置的情况下,将很难调试。
  • 嘿 Xav,抱歉,我认为我的第一篇文章 (stackoverflow.com/questions/17465353/…) 足以了解我的任务是如何创建的。我编辑我的帖子并添加完整的 build.gradle 文件。
  • 我将 AS 更新到 0.2.6 -> 仍然遇到同样的问题 :(

标签: android gradle android-studio build.gradle


【解决方案1】:

我遇到了和你一样的问题,并阅读了 0.5.5 的发行说明,找到了答案。

“访问变体容器不会强制创建任务。 这意味着android.[application|Library|Test]Variants 在评估阶段将为空。要使用它,请使用.all 而不是.each"

【讨论】:

【解决方案2】:

如果您想尝试 Alécio 的解决方案并在较新版本的 gradle 上出现弃用警告,例如

警告 [Project: :] variant.getProcessManifest() 已弃用。称呼 而是在 variant.getOutputs() 之一上。

您需要使用 'variant.outputs.each { output ->' 来迭代每个输出,请参见下面的代码

applicationVariants.all { variant ->
    def flavor = variant.productFlavors[0].name
    def flavorPackageName = variant.productFlavors[0].applicationId
    variant.outputs.each { output ->
        output.processManifest.doLast {
            println("configuring AndroidManifest.xml for  " + flavor);
            copy {
                from("${buildDir}/intermediates/manifests") {
                    include "${variant.dirName}/AndroidManifest.xml"
                }
                into("${buildDir}/intermediates/filtered_manifests")
            }

            def manifestFile = new File("${buildDir}/intermediates/filtered_manifests/${variant.dirName}/AndroidManifest.xml")
            def content = manifestFile.getText()
            def updatedContent = content.replaceAll("STRING_TO_BE_REPLACED", "NEW_STRING")
            manifestFile.write(updatedContent)
        }
        output.processResources.manifestFile = new File("${buildDir}/intermediates/filtered_manifests/${variant.dirName}/AndroidManifest.xml")
    }
}

【讨论】:

    【解决方案3】:

    以下代码可以放在您的 gradle 构建中的 android 块内。

    android {  
    
    ...
    
       buildTypes {
    
        ...
    
        applicationVariants.all { variant ->
            def flavor = variant.productFlavors[0].name
            def flavorPackageName = variant.productFlavors[0].applicationId
            variant.processManifest.doLast {
                println("configuring AndroidManifest.xml for  " + flavor);
                copy {
                    from("${buildDir}/intermediates/manifests") {
                        include "${variant.dirName}/AndroidManifest.xml"
                    }
                    into("${buildDir}/intermediates/filtered_manifests")
                }
    
                def manifestFile = new File("${buildDir}/intermediates/filtered_manifests/${variant.dirName}/AndroidManifest.xml")
                def content = manifestFile.getText()
                def updatedContent = content.replaceAll("STRING_TO_BE_REPLACED", "NEW_STRING")
                manifestFile.write(updatedContent)
            }
            variant.processResources.manifestFile = new File("${buildDir}/intermediates/filtered_manifests/${variant.dirName}/AndroidManifest.xml")
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-07-02
      • 1970-01-01
      • 2012-10-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多