문자열 유형으로 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.