문자열 유형으로 buildConfigField를 생성하는 방법


145

Android Studio프로젝트에는 두 가지 build configuration가 있습니다 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'
    }
}

다음과 같이 오류가 발생했습니다.

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

생성 된 내용 BuildConfig.java은 다음과 같습니다.

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

나는 생각 APP_VERSION하고 SERVER_URL문자열들은 따옴표가없는 입력 것으로 제대로 생성되지 않아요.

왜 그런 식으로 생성되는지 잘 모르겠습니다. 이 문제를 어떻게 해결할 수 있는지 알려주십시오.


큰 따옴표로 값 주위에 작은 따옴표를 추가하십시오. buildConfigField "String", APP_VERSION, ' "0.0.1" '(공백없이)
Pierre

답변:


254

문자열 유형 빌드 구성 필드는 다음과 같이 선언해야합니다.

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

따옴표 안의 필드 이름, 이스케이프 된 따옴표 안의 필드 값


1
질문은 'SERVER_URL'을 변수로 사용하려고했습니다. "SERVER_URL"을 따옴표로 묶으면 값이 문자열 리터럴이됩니다. 따라서 @madhead의 답변이 더 정확합니다 (더 예쁘다).
Will Vanderhoef

1
@ WillVanderhoef, 당신은 완전히 잘못되었습니다. SERVER_URL따옴표로 묶지 않으면 단순히 작동하지 않습니다 . 댓글을 달기 전에 직접 해보면 알 것입니다. 오류 메시지는Error:(32, 0) Could not find property 'SERVER_URL' on BuildType_...
Vladyslav Matviienko

내 잘못이야. 나는 Simas의 대답을 기본으로 사용하여 방금 복사했습니다. 내 요점은 세 번째 필드 (변수 이름)가 아니라 변수 값을 이스케이프 처리하기 위해 큰 따옴표를 사용하는 것에 관한 것입니다. 변수 자체에 큰 따옴표가 없으면 간단히 작은 따옴표를 사용하여 백 슬래시를 제거 할 수 있습니다. 두 답변을 모두 편집했습니다.
madhead

@VladMatvienko는 확실히 작동합니다. 실제로 설명하는 방식으로 사용하고 있습니다. def FIELD_NAME = "SERVER_URL"buildConfigField "boolean", FIELD_NAME, "false"함께 잘 작동합니다. SERVER_URL 정의가 누락되면 작동이 중단 될 수 있습니다.
Will Vanderhoef

2
@WillVanderhoef, 예, 그것은 당신이 언급하는 것을 잊어 버렸습니다-당신은 정의하는 동안 따옴표를 사용합니다. 따라서 솔루션에는 1 줄이 더 있고 따옴표도 사용하므로 그것이 나만큼 좋지 않습니다.
Vladyslav Matviienko

96

왜 모두가 큰 따옴표를 이스케이프하는 것에 대해 화가 났습니까? 못 생겼어! 이것은 Groovy입니다. 작은 따옴표와 큰 따옴표를 섞을 수 있습니다.

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

5
그것은 여전히 ​​갈 길이 아닌데, String이기 때문에 이스케이프하거나 중첩 된 따옴표를 사용할 필요는 없습니다
Fabio

4
@Fabio 중첩 따옴표를 사용하면 평가할 수있는 표현식을 사용할 수 있습니다. 이 답변을 참조하십시오 .
Albert Vila Calvo

31

"문제를 해결하는 것"이 ​​리터럴을 큰 따옴표로 묶을 필요가 없다는 것을 의미한다면, 의도 한대로 작동하는 것처럼 보이지 않습니다.

해결 방법으로 리터럴을 " gradle.properties "로 이동하여 잠재적으로 여러 못생긴 줄을 하나의 못생긴 줄로 바꾸는 실험을 해왔 습니다.

이렇게 :

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

추가 생각 :


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

빌드 구성 필드가 있고 동일한 gradle의 myn def에서 해당 변수에 액세스하려고합니다 .. plz helpp를 gradle하는 것이 처음입니다 !!
Adeel Turk

CONFIG 스크립트에 감사드립니다! 팀에서 var가 존재하지 않는 경우 예외가 발생하도록 약간 개선했습니다. CONFIG = { k -> if (project.properties.containsKey(k)) "\"${project.properties.get(k)}\"" else throw new RuntimeException("No such variable: " + k) }
demaksee

9

나도 혼란 스러웠다. 그러나 "문자열"은 필드 유형을 정의하지만 필드 값은 자동으로 인용되지 않으므로 여기에서 표현식을 사용할 수 있습니다.

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

그렇지 않으면 불가능합니다.


다음과 같이 문자열 보간을 사용하면 가능합니다. buildConfigField "String", "TEST", "\"$ {10} \ ""이 방법으로 빌드 파일에서도 메소드 또는 변수를 사용할 수 있습니다.
Szörényi Ádám

9

당신의 문자열 따옴표를 탈출 :

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

5

사용하다

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

변수. 여기 에서 참조


2

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

그런 다음 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
코드 전용 답변은 실제로 권장하지 않습니다. 미래의 독자들을 돕기 위해 당신이하고있는 일도 설명해주세요!
itsmysterybox

다음 번에는 복사 붙여 넣기 대신 이전 답변 stackoverflow.com/a/53056170/1084764 참조
Raykud

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.