Como gerar buildConfigField com o tipo String

145

No meu Android Studioprojeto, existem dois build configurationcom alguns buildConfigField:

    buildTypes {
    def SERVER_URL = "SERVER_URL"
    def APP_VERSION = "APP_VERSION"

    debug {
        buildConfigField "String", SERVER_URL, "http://dev.myserver.com"
        buildConfigField "String", APP_VERSION, "0.0.1"
    }

    release {
        buildConfigField "String", SERVER_URL, "https://myserver.com"
        buildConfigField "String", APP_VERSION, "0.0.1"

        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

Estou recebendo e erro da seguinte maneira:

/path/to/generated/BuildConfig.java
    Error:(14, 47) error: ';' expected
    Error:(15, 47) error: ';' expected

o gerado BuildConfig.javaé o seguinte:

public final class BuildConfig {
    public static final boolean DEBUG = Boolean.parseBoolean("true");
    public static final String APPLICATION_ID = "com.mycuteoffice.mcoapp";
    public static final String BUILD_TYPE = "debug";
    public static final String FLAVOR = "";
    public static final int VERSION_CODE = 1;
    public static final String VERSION_NAME = "1.0";
    // Fields from build type: debug
    public static final String APP_VERSION = 0.0.1;
    public static final String SERVER_URL = http://dev.mycuteoffice.com;
}

Eu acho que o APP_VERSIONe SERVER_URLnão está sendo gerado corretamente como sendo do tipo String, eles não têm aspas.

Não sei por que está sendo gerado dessa maneira. Informe-me como posso resolver esses problemas.

Abdullah
fonte
Basta adicionar aspas simples em torno do valor com aspas duplas: buildConfigField "String", APP_VERSION, ' "0.0.1" '(sem espaços, é claro)
Pierre

Respostas:

254

Os campos de configuração de construção do tipo string devem ser declarados assim:

buildConfigField "String", "SERVER_URL", "\"http://dev.myserver.com\""

o nome do campo entre aspas, o valor do campo nas aspas escapadas adicionalmente.

Vladyslav Matviienko
fonte
1
A questão pretendia usar 'SERVER_URL' como uma variável. Colocar "SERVER_URL" entre aspas torna o valor literal em String. A resposta de @ madhead é, portanto, mais correta (e mais bonita).
Will Vanderhoef 21/07
1
@WillVanderhoef, você está completamente errado. Simplesmente não funciona se você não colocar SERVER_URLaspas. Você saberia se tentasse antes de comentar. A mensagem de erro éError:(32, 0) Could not find property 'SERVER_URL' on BuildType_...
Vladyslav Matviienko
Foi mal. Eu usei a resposta de Simas como base e apenas a copiei. Meu argumento não era sobre o terceiro campo (nome da variável), mas sobre o uso de aspas duplas para escapar do valor da variável: se a variável em si não tiver aspas duplas, você pode simplesmente colocar aspas externas para se livrar das barras invertidas. Eu editei as duas respostas.
madhead
@VladMatvienko definitivamente funciona, na verdade estou usando da maneira que descrevo. def FIELD_NAME = "SERVER_URL"e buildConfigField "boolean", FIELD_NAME, "false"trabalhar bem juntos. Se você não encontrar a definição de SERVER_URL, poderá travar, provavelmente é o que está fazendo de errado.
Will Vanderhoef
2
@ WillVanderhoef, sim, foi o que você esqueceu de mencionar - você usa as aspas durante a definição. Portanto, sua solução possui 1 linha extra e usa aspas também, e é por isso que não é tão boa quanto a minha.
Vladyslav Matviienko 01/09/16
96

Por que todo mundo está tão louco por escapar de aspas duplas? Parece feio! Isso é Groovy, pessoal, você pode misturar aspas simples e duplas:

buildConfigField "String", 'SERVER_URL', '"http://dev.myserver.com"'
buildConfigField "String", 'APP_VERSION', '"0.0.1"'
louco
fonte
5
Ainda não é o caminho a seguir, não devemos escapar ou usar aspas aninhadas, pois é String
Fabio
4
@Fabio O uso de aspas aninhadas permite o uso de expressões que podem ser avaliadas. Veja esta resposta .
Albert Vila Calvo
31

Se, ao "resolver os problemas", você quer dizer não precisar colocar aspas literais, não encontrei nada, pois parece estar funcionando conforme o planejado.

Eu tenho experimentado mover os literais para " gradle.properties " como uma solução alternativa, transformando potencialmente várias linhas feias em uma linha feia.

Igual a:

buildTypes {
def SERVER_URL = "SERVER_URL"
def APP_VERSION = "APP_VERSION"

def CONFIG = { k -> "\"${project.properties.get(k)}\"" }

debug {
    buildConfigField "String", SERVER_URL, CONFIG("debug.server.url")
    buildConfigField "String", APP_VERSION, CONFIG("version")
}

release {
    buildConfigField "String", SERVER_URL, CONFIG("release.server.url")
    buildConfigField "String", APP_VERSION, CONFIG("version")

    minifyEnabled false
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}

gradle.properties

version=0.1.1
...
debug.server.url=http://dev.myserver.com
...
release.server.url=http://myserver.com
...

Pensamentos adicionais:


def CONFIG = { b,k -> "\"${project.properties.get(b+'.'+k)}\"" }
def CONFIG_DEBUG = { k -> CONFIG('debug',k) }
def CONFIG_RELEASE = { k -> CONFIG('release',k) }

def CONFIG = { b,k -> "\"${project.properties.get(b+'.'+k)}\"" }
def CONFIG_INT = { b,k -> "${project.properties.get(b+'.'+k)}" }
...
Primexx
fonte
Eu tenho um campo de configuração de compilação e eu quero acessar essa variável em myn def no mesmo gradle .. eu sou novo para gradle plz helpp !!
10248 Adeel Turk
Obrigado pelo script CONFIG! Em time que melhorou ligeiramente-lo para jogar exceção se var não existe: CONFIG = { k -> if (project.properties.containsKey(k)) "\"${project.properties.get(k)}\"" else throw new RuntimeException("No such variable: " + k) }
demaksee
9

Eu também estava confuso. Mas há um sentido - "String" define o tipo do campo, enquanto o valor do campo não é citado automaticamente para permitir o uso de expressões aqui:

buildConfigField "String", "TEST", "new Integer(10).toString()"

Caso contrário, não seria possível.

geiger
fonte
É possível se você usar interpolação de string, por exemplo: buildConfigField "String", "TEST", "\" $ {10} \ "" Dessa forma, você também pode usar métodos ou variáveis ​​em seu arquivo de construção.
Szörényi Ádám
9

Escapa suas citações de string:

buildConfigField "String", 'SERVER_URL', "\"http://dev.myserver.com\""
buildConfigField "String", 'APP_VERSION', "\"0.0.1\""
Simas
fonte
5

Usar

 buildConfigField "String", "FILE_NAME", "\"{$fileName}\"" 

para variável. Referência daqui

Audi
fonte
2

no aplicativo build.gradle

def buildTimeAndVersion = releaseTime() + "-" + getSvnVersion()    
buildTypes {
debug {
    signingConfig signingConfigs.config
    buildConfigField "String", 'BIULD_TIME', "\"${buildTimeAndVersion}\""
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
...
}

static def releaseTime() {
return new Date().format("yyyyMMdd", TimeZone.getDefault())
}

def getSvnVersion() {
def pro = ("svnversion -c " + getBuildDir().parent).execute()
pro.waitFor()
def version = pro.in.text
Pattern p = Pattern.compile("(\\d+\\:)?(\\d+)\\D?")
Matcher m = p.matcher(version)
if (m.find()) {
version = m.group(m.groupCount())
}
try {
return version
} catch (e) {
println e.getMessage()
}
return 0
}

depois no BuildConfig

public final class BuildConfig {  
public static final boolean DEBUG = Boolean.parseBoolean("true");   
public static final String APPLICATION_ID = "xxx.xxxxxxxx.xxx";   
public static final String BUILD_TYPE = "debug";  
public static final String FLAVOR = "";  
public static final int VERSION_CODE = 53;  
public static final String VERSION_NAME = "5.4.4";  
// Fields from build type: debug  
public static final String BIULD_TIME = "20181030-2595";  
}
yitai wei
fonte
1
As respostas apenas de código são realmente desencorajadas. Para ajudar futuros leitores, explique o que você está fazendo também!
itsmysterybox
e da próxima vez, referência à sua resposta anterior stackoverflow.com/a/53056170/1084764 em vez de apenas copiar e colar
Raykud
0

Apenas \ " my stuff\" funcionou para mim. E eu tenho todos os tipos de personagens estranhos my stuff.

Sevastyan Savanyuk
fonte