Cómo generar buildConfigField con tipo String

145

En mi Android Studioproyecto hay dos build configurationcon algunos 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'
    }
}

Estoy obteniendo y error de la siguiente manera:

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

el generado BuildConfig.javaes el siguiente:

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;
}

Creo que APP_VERSIONy SERVER_URLno se están generando correctamente como tipo de cadena, no tienen comillas.

No estoy seguro de por qué se está generando de esa manera. Avíseme cómo puedo resolver estos problemas.

Abdullah
fuente
Simplemente agregue comillas simples alrededor del valor con comillas dobles: buildConfigField "String", APP_VERSION, ' "0.0.1" '(sin espacios, por supuesto)
Pierre

Respuestas:

254

Los campos de configuración de compilación de tipo de cadena deben declararse así:

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

el nombre del campo entre comillas, el valor del campo en comillas escapadas adicionalmente.

Vladyslav Matviienko
fuente
1
La Cuestión pretendía usar 'SERVER_URL' como variable. Poner "SERVER_URL" entre comillas hace que el valor sea un literal de cadena. La respuesta de @ madhead es, por lo tanto, más correcta (y más bonita).
Will Vanderhoef
1
@WillVanderhoef, estás completamente equivocado. Simplemente no funciona si no se pone SERVER_URLentre comillas. Lo sabrías si lo probaras antes de comentar. El mensaje de error esError:(32, 0) Could not find property 'SERVER_URL' on BuildType_...
Vladyslav Matviienko
Culpa mía. Usé la respuesta de Simas como base y simplemente la copié. Mi punto no era sobre el tercer campo (nombre de la variable), sino sobre el uso de comillas dobles para escapar del valor de la variable: si la variable en sí misma no tiene comillas dobles, puede simplemente comillas externas simples para deshacerse de las barras invertidas. He editado ambas respuestas.
madhead
@VladMatvienko definitivamente funciona, en realidad lo estoy usando como lo describo. def FIELD_NAME = "SERVER_URL"ybuildConfigField "boolean", FIELD_NAME, "false" trabajan bien juntos. Si falta la definición de SERVER_URL, se bloqueará, probablemente eso es lo que está haciendo mal.
Will Vanderhoef
2
@WillVanderhoef, sí, eso es lo que olvidó mencionar: utiliza las citas durante la definición. Entonces, su solución tiene 1 línea adicional, y también usa comillas, y por eso no es tan buena como la mía.
Vladyslav Matviienko
96

¿Por qué todos están tan enojados por escapar de las comillas dobles? ¡Parece feo! Esto es Groovy, muchachos, pueden mezclar comillas simples y dobles:

buildConfigField "String", 'SERVER_URL', '"http://dev.myserver.com"'
buildConfigField "String", 'APP_VERSION', '"0.0.1"'
loco
fuente
55
Todavía no es el camino a seguir, no deberíamos tener que escapar o usar comillas anidadas ya que es String
Fabio
44
@Fabio El uso de comillas anidadas permite usar expresiones que se pueden evaluar. Mira esta respuesta .
Albert Vila Calvo
31

Si "resolviendo los problemas" quiere decir que no tiene que hacer dobles comillas literales, no he encontrado nada, ya que parece estar funcionando según lo diseñado.

He estado experimentando con mover los literales a " gradle.properties " como una solución alternativa, convirtiendo potencialmente varias líneas feas en una sola línea fea.

Al igual que:

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
...

Pensamientos adicionales:


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
fuente
Tengo un campo de configuración de compilación y quiero acceder a esa variable en myn def en el mismo gradle. ¡Soy nuevo en gradle, por favor ayuda!
Adeel Turk
¡Gracias por el guión CONFIG! En el equipo lo mejoramos ligeramente para lanzar una excepción si var no existe: CONFIG = { k -> if (project.properties.containsKey(k)) "\"${project.properties.get(k)}\"" else throw new RuntimeException("No such variable: " + k) }
demaksee
9

Estaba confundido también. Pero hay un sentido: "String" define el tipo de campo, mientras que el valor del campo no se cita automáticamente para permitirnos usar expresiones aquí:

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

De lo contrario, no sería posible.

Geiger
fuente
Es posible si usa la interpolación de cadenas, por ejemplo: buildConfigField "String", "TEST", "\" $ {10} \ "" De esta manera también puede usar métodos o variables en su archivo de construcción.
Szörényi Ádám
9

Escapar de sus comillas:

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

Utilizar

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

para variable. Referencia desde aquí

Audi
fuente
2

en la aplicación 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
}

luego en 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
fuente
1
Las respuestas de solo código están realmente desaconsejadas. Para ayudar a los futuros lectores, ¡explique también lo que está haciendo!
itsmysterybox
y la próxima vez referencia a su respuesta anterior stackoverflow.com/a/53056170/1084764 en lugar de simplemente copiar y pegar
Raykud
0

Solo \ " my stuff\" funcionó para mí. Y tengo todo tipo de personajes extraños my stuff.

Sevastyan Savanyuk
fuente