Jak wygenerować buildConfigField z typem String


145

W moim Android Studioprojekcie są dwa build configurationz kilkoma 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'
    }
}

Otrzymuję i błąd w następujący sposób:

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

generowany BuildConfig.javajest następujący:

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

Myślę, że APP_VERSIONi SERVER_URLnie są generowane poprawnie, ponieważ są typu String, nie mają cudzysłowów.

Nie jestem pewien, dlaczego jest generowany w taki sposób. Daj mi znać, jak mogę rozwiązać ten problem.


Po prostu dodaj pojedyncze cudzysłowy wokół wartości z podwójnymi cudzysłowami: buildConfigField "String", APP_VERSION, ' "0.0.1" '(oczywiście bez spacji)
— Pierre

Odpowiedzi:


254

Pola konfiguracji budowania typu ciągowego należy zadeklarować w następujący sposób:

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

nazwa pola w cudzysłowie, dodatkowo wartość pola w cudzysłowie.


1
Pytanie miało na celu użycie „SERVER_URL” jako zmiennej. Umieszczenie „SERVER_URL” w cudzysłowie powoduje, że wartość staje się literałem typu String. Dlatego odpowiedź @ madhead jest poprawniejsza (i ładniejsza).
— Will Vanderhoef,

1
@WillVanderhoef, całkowicie się mylisz. Po prostu nie działa, jeśli nie umieścisz go SERVER_URLw cudzysłowie. Wiedziałbyś o tym, gdybyś spróbował sam przed komentarzem. Komunikat o błędzie toError:(32, 0) Could not find property 'SERVER_URL' on BuildType_...
— Vladyslav Matviienko

Mój błąd. Użyłem odpowiedzi Simasa jako podstawy i po prostu ją skopiowałem. Nie chodziło mi o trzecie pole (nazwa zmiennej), ale o używanie podwójnych cudzysłowów do ucieczki wartości zmiennej: jeśli sama zmienna nie ma podwójnych cudzysłowów, możesz po prostu pojedyncze zewnętrzne cudzysłowy, aby pozbyć się odwrotnych ukośników. Zredagowałem obie odpowiedzi.
— szalony

@VladMatvienko zdecydowanie działa, właściwie używam go tak, jak opisuję. def FIELD_NAME = "SERVER_URL"i buildConfigField "boolean", FIELD_NAME, "false"dobrze ze sobą współpracować. Jeśli brakuje definicji SERVER_URL, nastąpi awaria, prawdopodobnie to właśnie robisz źle.
— Will Vanderhoef

2
@WillVanderhoef, tak, o tym zapomniałeś wspomnieć - używasz cudzysłowów podczas definicji. Twoje rozwiązanie ma 1 dodatkową linię i również używa cudzysłowów, dlatego nie jest tak dobre jak moje.
— Vladyslav Matviienko

96

Dlaczego wszyscy tak szaleni unikają podwójnych cudzysłowów? Wygląda brzydko! To jest Groovy, chłopaki, możecie po prostu mieszać pojedyncze i podwójne cudzysłowy:

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

5
To wciąż nie jest droga, nie powinniśmy musieć uciekać ani używać zagnieżdżonych cudzysłowów, ponieważ jest to String
— Fabio

4
@Fabio Używanie zagnieżdżonych cudzysłowów pozwala na użycie wyrażeń, które można ocenić. Zobacz tę odpowiedź .
— Albert Vila Calvo,

31

Jeśli przez „rozwiązywanie problemów” masz na myśli brak konieczności podwójnego cytowania literałów, nie znalazłem niczego, ponieważ wydaje się, że działa zgodnie z założeniami.

Eksperymentowałem z przeniesieniem literałów do „ gradle.properties ” jako obejściem, zamieniając potencjalnie wiele brzydkich wierszy w jeden brzydki wiersz.

Tak jak to:

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

Dalsze przemyślenia:


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

Mam pole konfiguracji kompilacji i chcę uzyskać dostęp do tej zmiennej w myn def w tym samym gradle .. Jestem nowy w gradle plz helpp!
— Adeel Turk

Dzięki za skrypt CONFIG! W drużynie nieznacznie poprawiliśmy to, aby wyrzucić wyjątek, jeśli var nie istnieje: CONFIG = { k -> if (project.properties.containsKey(k)) "\"${project.properties.get(k)}\"" else throw new RuntimeException("No such variable: " + k) }
— demaksee

9

Ja też byłem zdezorientowany. Ale ma sens - „String” definiuje typ pola, podczas gdy wartość pola nie jest automatycznie cytowana, abyśmy mogli użyć tutaj wyrażeń:

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

W przeciwnym razie nie byłoby to możliwe.


Jest to możliwe, jeśli używasz interpolacji ciągów, np .: buildConfigField "String", "TEST", "\" $ {10} \ "" W ten sposób możesz również użyć metod lub zmiennych w pliku kompilacji.
— Szörényi Ádám

9

Uniknij cudzysłowów:

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

5

Posługiwać się

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

dla zmiennej. Odniesienie stąd


2

w aplikacji 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
}

następnie w 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
Tylko kod odpowiedzi są naprawdę zniechęcone. Aby pomóc przyszłym czytelnikom, wyjaśnij, co robisz!
— itsmysterybox

i następnym razem odniesienie do poprzedniej odpowiedzi stackoverflow.com/a/53056170/1084764 zamiast po prostu kopiować wklejanie
— Raykud

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.