当前位置: 首页 > 知识库问答 >
问题:

编辑谷歌服务。Gradle中不同口味的json

马晓博
2023-03-14

回答在这里。

我的应用程序中有不止一种风格,我想使用相同的谷歌服务。json对于所有这些,所以我考虑将属性package_name的值设置为正则表达式,并在我的构建中使用任务替换它。gradle(应用程序模块)。

我的口味是这样定义的:

android {
    productFlavors {
        FirstFlavor {
            applicationId "com.thisapp.first"
            versionCode = 1
            versionName "1.0"
        }
        SecondFlavor {
            applicationId "com.myapp.second"
            versionCode = 1
            versionName "1.0"
        }
    }
}

我的想法是:

task runBeforeBuild(type: Exec) {
    def google_json = file('./google-services.json')
    google_json.getText().replace('${package_name_value}', myPackageName)
}

问题是我不知道如何访问PackageName(代码中的myPackageName),或者是否可能。

也许我必须使用另一个任务,而不是在构建之前运行,我对Gradle不太熟悉。

共有2个答案

戚勇
2023-03-14

首先,我必须解释我使用Jenkins来编译我的应用程序,所以构建过程与Android Studio中的不完全相同。在我的例子中,Jenkins只构建了发布版本,并且没有以与IDE相同的方式获得味道。我将解释这两种解决方案:

构建中。gradle(模块:应用程序)

我的

buildscript{
...
}
android {
...
}

afterEvaluate {
    android.applicationVariants.all { variant ->
        preBuild.doLast {
            setGoogleServicesJson(variant)
        }
    }
    // Only for Jenkins
    assembleRelease.doFirst {
        deleteGoogleServicesJson()
    }
}

def setGoogleServicesJson(variant) {
    def originalFileName = "google-services.bak"
    def newFileName = "google-services.json"
    def originalFile = "./$originalFileName"
    def newFile = "./$newFileName"
    def applicationId = variant.applicationId
    def regularExpression = "\\\"package_name\\\" : \\\"(\\w(\\.\\w)?)+\\\""
    def packageName = "\\\"package_name\\\" : \\\"$applicationId\\\""

    copy {
        from (originalFile)
        into ("./")
        rename (originalFileName, newFileName)
    }
    ant.replaceregexp(
            file: newFile,
            match: regularExpression,
            replace: packageName,
            byLine: true)
}

def deleteGoogleServicesJson() {
    file("./google-services.json").delete()
}

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

詹金斯正在获得谷歌的服务。json位于“Project/app/”文件夹中,它不使用flavor,因此对于每个变体,我会尽快(在预构建任务之后)从我的代码创建一个新的json。bak文件,覆盖包名称,让Gradle继续构建。

当一切都完成后,在它发布应用程序(assembleRelease.doFirst)之前,我删除了google-services.json,并保留了*. bak

在我的例子中,我只想更改我的JSON的包名称值,但是如果我想更改另一个值,如项目编号、客户端id或其他任何取决于味道的值,这个解决方案将不起作用。

替代解决方案(使用口味)

afterEvaluate {
    android.applicationVariants.all { variant ->
        def fileName = "google-services.json"
        def originalFile = "./$fileName"
        def flavorName = variant.flavorName
        def destinationPath = "."
        // If there is no flavor we use the original path
        if (!flavorName.empty) {
            destinationPath = "$destinationPath/src/$flavorName/"
            copy {
                from file(originalFile)
                into destinationPath
            }
        }
        def regularExpression = "\\\"package_name\\\" : \\\"(\\w(\\.\\w)?)+\\\""
        def packageName = "\\\"package_name\\\" : \\\"$variant.applicationId\\\""
        ant.replaceregexp(
                file: "./$destinationPath/$fileName",
                match: regularExpression,
                replace: packageName, 
                byLine: true)
    }
}

在这个解决方案中,我将google-services.json放在'Project/app/'文件夹中,并在每个味道文件夹中复制它。然后我覆盖package_name。如果您在没有味道的情况下工作,应用程序将使用原始JSON进行编译。

您可以在覆盖它之前检查flavor文件夹中是否存在另一个JSON,以防其他值的值不同。

我找到了一个混合这个和这个答案的解决方案。

这是我的构建。gradle(模块:应用程序)现在:

afterEvaluate {
    android.applicationVariants.all { variant ->
        def applicationId = variant.applicationId
        ant.replaceregexp(file: './google-services.json', match:'package_name_value', replace: applicationId, byLine: true)
    }
}

其中,package\u name\u value是我定义要替换的“正则表达式”。

谷歌服务的位置。json是“MyProject/ppp/google services.json”,我已经测试过了,如果你放另一个googler服务。json在您的flavor文件夹中,它覆盖了第一个。

*当您同时定义了多个风格时,会(至少)出现一个问题,因为此任务总是覆盖同一个文件,因此最终的应用程序id将是您定义的最后一个。

如果你有其他方法,请随时发布。

韩烈
2023-03-14

我找到了另一种方法,并想分享它。请注意,这是我第一次使用gradle编写一些任务,因此代码根本不是最佳的(目前我不能花更多时间来改进它)。

我做的很简单。

1) 就在任务处理之前,即来自谷歌服务的任务将读取谷歌服务。json文件,我触发一些代码来更新谷歌服务。json文件。为此:

gradle.taskGraph.beforeTask { Task task ->
    if (task.name.startsWith("process") && task.name.endsWith("GoogleServices")) {
    }
}

2)从任务名称中检索当前的味道和buildType(任务名称的示例:以进程'Flavor"BuildType'GoogleServices的形式显示的Process ProdReleaseGoogleServices)

String currentFlavor = task.name.replace("process", "").replace("GoogleServices", "")
currentFlavor = currentFlavor.toLowerCase()

3) 从currentFlavor变量中删除buildType。为了做到这一点,我只需循环遍历项目中的所有buildType,并将其从currentFlavor变量中删除

android.applicationVariants.all { variant ->
    currentFlavor = currentFlavor.replace(variant.buildType.name, "")
}

此时,变量电流Flavor具有电流Flavor(例如“prod”)

4)从我的build.gradle中定义的口味中检索包名

在我的身材中。gradle,我为每种口味指定了包装名称:

productFlavors {
    prod {
        applicationId 'packageName1'
    }
    rec {
        applicationId 'packageName2'
    }
}

我这样检索它:(包名返回时带有[],因此我必须删除它们。例如,我将检索[packageName1])

String currentApplicationId;
android.applicationVariants.all { variant ->
    if (variant.flavorName == currentFlavor) {
        currentApplicationId = variant.productFlavors.applicationId.toString().replace("[", "").replace("]", "")
    }
}

5)现在我有了当前构建的包名称,我只需要打开当前google-services.json文件,并更新其中的包名称。为此,我添加了一个方法updateGoogleServicesJsonFile。小心更改第二行的filePath以指向您的位置。

def updateGoogleServicesJsonFile(applicationId) {
    File file = new File(getProjectDir(), "/google-services.json")
    if (!file.exists())
    {
        project.logger.log(LogLevel.ERROR, "Error updating the google-services.json because the file doesn't exists...")
        return
    }

    List<String> lineList = file.readLines()
    for (int i = 0; i < lineList.size(); i++)
    {
        if (lineList.get(i).trim().startsWith("\"package_name\": \""))
        {
            String line = lineList.get(i)
            line = line.substring(0, line.indexOf(":") + 1)
            line += " \"" + applicationId + "\""

            lineList.set(i, line)
        }
    }

    file.write(lineList.join("\n"))
}

这就是在执行读取任务之前更新google-services.json文件的一些代码。

def updateGoogleServicesJsonFile(applicationId) {
    File file = new File(getProjectDir(), "/google-services.json")
    if (!file.exists())
    {
        project.logger.log(LogLevel.ERROR, "Error updating the google-services.json because the file doesn't exists...")
        return
    }

    List<String> lineList = file.readLines()
    for (int i = 0; i < lineList.size(); i++)
    {
        if (lineList.get(i).trim().startsWith("\"package_name\": \""))
        {
            String line = lineList.get(i)
            line = line.substring(0, line.indexOf(":") + 1)
            line += " \"" + applicationId + "\""

            lineList.set(i, line)
        }
    }

    file.write(lineList.join("\n"))
}

gradle.taskGraph.beforeTask { Task task ->
    // Before the task processFlavorBuildTypeGoogleServices (such as processProdReleaseGoogleServices), we update the google-services.json
    if (task.name.startsWith("process") && task.name.endsWith("GoogleServices")) {
        // Getting current flavor name out of the task name
        String currentFlavor = task.name.replace("process", "").replace("GoogleServices", "")
        currentFlavor = currentFlavor.toLowerCase()

        android.applicationVariants.all { variant ->
            currentFlavor = currentFlavor.replace(variant.buildType.name, "")
       }

        // Getting current application id that are defined in the productFlavors
        String currentApplicationId;
        android.applicationVariants.all { variant ->
            if (variant.flavorName == currentFlavor) {
                currentApplicationId = variant.productFlavors.applicationId.toString().replace("[", "").replace("]", "")
            }
        }

       updateGoogleServicesJsonFile(currentApplicationId)
    }
}
 类似资料:
  • null 我尝试过的相关帖子: 从单个生成类型生成使用不同密钥签名的多个生成 这需要为每种口味配置 它似乎没有使用我自定义的 null null 我的的重要部分如下所示:

  • 当我在我的服务器上用wget、curl或python爬行谷歌搜索引擎时,我遇到了一个非常奇怪的问题。Google将我重定向到以[ipv4 | ipv6]开头的地址。谷歌。fr/抱歉/索引重定向。。。最后发送503错误,服务不可用。。。 有时抓取工作正常,有时不是在白天,我尝试了几乎所有可能的方法:强制ipv4/ipv6而不是主机名、引用者、用户代理、vpn、. com/. fr/、代理和tor,.

  • 我知道这个问题已经被问过了,但是问题仍然存在于任何版本的com.google.gms:google-services 4.2.0以上:我的google-services.json文件的搜索位置不再考虑风味植物学。 上面只写着: 文件谷歌服务。缺少json。没有它,谷歌服务插件就无法运行。 搜索位置:~/app/google-services.json 而不是~/app/src/TopfavorSu

  • 我想在Java项目中包含V8(“J2V8”)的Java绑定。原因是:(i)V8 JavaScript引擎比JRE附带的JavaScript引擎快得多;(ii)我使用的库仅在JavaScript中可用,并且要花费大量的精力到Java端口。 null 我目前正在创建脂肪罐子使用阴影插件。 注意,该项目不是Android项目。在那里,有了Android插件,这似乎是直截了当的。 第一个想法是引入配置和特

  • 上述代码的结果是: 已打开。服务帐户客户端 ID 在 GSuite 中使用适当的作用域进行授权。 服务帐户适用于普通凭据。它只适用于委托凭证。 我在我们的域中尝试了不同的API(范围)和不同的用户。 我有一个同事试图从头开始编写一个样本,他得到了同样的东西。

  • 问题内容: 我正在按照http://googcloudlabs.appspot.com/教程创建新的Google App Engine项目。当我尝试从本地主机运行时,却按如下所述抛出错误,但是当我将其部署正常时。(http://mynewcloudcom.appspot.com/)。请帮忙。 Eclipse控制台 问题答案: 找到了答案。我需要在JDK1.6中运行。一旦我更改了Java编译器(右键