วิธีสร้าง 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" '(โดยไม่เว้นวรรค)
ปิแอร์

คำตอบ:


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

ฉันมีฟิลด์สร้าง config และฉันต้องการเข้าถึงตัวแปรนั้นใน def myn ใน gradle เดียวกัน .. ฉันใหม่เพื่อ gradle helz plz !!
Adeel Turk

ขอบคุณสำหรับการกำหนดค่าสคริปต์! ในทีมเราปรับปรุงให้ดีขึ้นเล็กน้อยเพื่อโยนข้อยกเว้นถ้าไม่มี 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\""


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.