Comment générer buildConfigField avec le type String


146

Dans mon Android Studioprojet, il y en a deux build configurationavec certains 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'
    }
}

Je reçois une erreur comme suit:

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

le généré BuildConfig.javaest le suivant:

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

Je pense que les APP_VERSIONet SERVER_URLne sont pas générés correctement en tant que type de chaîne, ils n'ont pas de guillemets.

Je ne sais pas pourquoi il est généré de cette manière. Veuillez me faire savoir comment puis-je résoudre ces problèmes.


Ajoutez simplement des guillemets simples autour de la valeur avec des guillemets doubles: buildConfigField "String", APP_VERSION, ' "0.0.1" '(sans espaces bien sûr)
Pierre

Réponses:


255

Les champs de configuration de construction de type chaîne doivent être déclarés comme ceci:

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

le nom du champ entre guillemets, la valeur du champ entre guillemets en plus.


1
La question avait pour but d'utiliser 'SERVER_URL' comme variable. Mettre "SERVER_URL" entre guillemets fait de la valeur un littéral String. La réponse de @ madhead est donc plus correcte (et plus jolie).
Will Vanderhoef

1
@WillVanderhoef, vous vous trompez complètement. Cela ne fonctionne tout simplement pas si vous ne mettez pas de SERVER_URLguillemets. Vous le sauriez si vous l'essayez vous-même avant de commenter. Le message d'erreur estError:(32, 0) Could not find property 'SERVER_URL' on BuildType_...
Vladyslav Matviienko

Ma faute. J'ai utilisé la réponse de Simas comme base et je l'ai juste copiée. Mon point n'était pas le troisième champ (nom de la variable), mais l'utilisation de guillemets doubles pour échapper à la valeur de la variable: si la variable elle-même n'a pas de guillemets doubles, vous pouvez simplement utiliser des guillemets externes simples pour vous débarrasser des contre-obliques. J'ai modifié les deux réponses.
madhead

@VladMatvienko fonctionne définitivement, je l'utilise en fait comme je le décris. def FIELD_NAME = "SERVER_URL"et buildConfigField "boolean", FIELD_NAME, "false"fonctionnent très bien ensemble. Si vous manquez la définition de SERVER_URL, vous planterez, c'est probablement ce que vous faites mal.
Will Vanderhoef

2
@WillVanderhoef, oui, c'est ce que vous avez oublié de mentionner - vous utilisez les guillemets lors de la définition. Donc, votre solution a 1 ligne supplémentaire et utilise également des guillemets, et c'est pourquoi elle n'est pas aussi bonne que la mienne.
Vladyslav Matviienko

96

Pourquoi tout le monde est-il si fou d'échapper aux guillemets? Ça a l'air moche! C'est Groovy, les gars, vous pouvez simplement mélanger des guillemets simples et doubles:

buildConfigField "String", 'SERVER_URL', '"http://dev.myserver.com"'
buildConfigField "String", 'APP_VERSION', '"0.0.1"'

5
Ce n'est toujours pas la voie à suivre, nous ne devrions pas avoir à échapper ou à utiliser des guillemets imbriqués car c'est une chaîne
Fabio

4
@Fabio L'utilisation de guillemets imbriqués permet d'utiliser des expressions qui peuvent être évaluées. Voyez cette réponse .
Albert Vila Calvo

31

Si par "résoudre les problèmes" vous voulez dire ne pas avoir à double guillemets littéraux, je n'ai rien trouvé car il semble fonctionner comme prévu.

J'ai expérimenté le déplacement des littéraux dans " gradle.properties " comme solution de contournement, transformant potentiellement plusieurs lignes laides en une ligne laide.

Ainsi:

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

Autres réflexions:


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)}" }
...

J'ai un champ de configuration de construction et je veux accéder à cette variable dans myn def dans le même gradle .. je suis nouveau à gradle plz helpp !!
Adeel Turk

Merci pour le script CONFIG! En équipe, nous l'avons légèrement amélioré pour lancer une exception si var n'existe pas: CONFIG = { k -> if (project.properties.containsKey(k)) "\"${project.properties.get(k)}\"" else throw new RuntimeException("No such variable: " + k) }
demaksee

9

J'étais également confus. Mais il y a un sens - "String" définit le type du champ, alors que la valeur du champ n'est pas automatiquement citée afin de nous permettre d'utiliser des expressions ici:

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

Sinon, ce ne serait pas possible.


C'est possible si vous utilisez l'interpolation de chaîne, par exemple: buildConfigField "String", "TEST", "\" $ {10} \ "" De cette façon, vous pouvez également utiliser des méthodes ou des variables dans votre fichier de construction.
Szörényi Ádám

9

Échappez vos guillemets de chaîne:

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

5

Utilisation

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

pour variable. Référence d' ici


2

dans l'application 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
}

puis dans 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";  
}

1
Les réponses au code uniquement sont vraiment déconseillées. Pour aider les futurs lecteurs, veuillez expliquer ce que vous faites aussi!
itsmysterybox

et la prochaine fois référence à votre réponse précédente stackoverflow.com/a/53056170/1084764 au lieu de simplement copier-coller
Raykud

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.