จะให้ไอคอนแอพ Android ที่แตกต่างกันสำหรับ gradle buildTypes ต่างๆได้อย่างไร?


107

ฉันมีการสร้างสองประเภทในไฟล์ gradle ของฉัน: debugและrelease. ฉันต้องการตั้งค่าไอคอนแอปอื่นสำหรับdebugประเภทบิวด์ มีวิธีใดบ้างในการทำเช่นนี้ผ่านประเภทการสร้างโดยไม่เข้ากับรสชาติของผลิตภัณฑ์? ไฟล์ build.gradle อยู่ด้านล่าง

apply plugin: 'android'

//...

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.3"

    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 19
        versionCode 30
        versionName "2.0"
    }
    buildTypes {
        debug {
            packageNameSuffix '.debug'
            versionNameSuffix '-SNAPSHOT'
        }
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}


คำตอบ:


165

คิดออก สิ่งที่คุณต้องทำคือสร้างโฟลเดอร์ src แยกที่เรียกdebugว่าเก็บไอคอนต่างๆ ตัวอย่างเช่นหากเค้าโครงโครงการของคุณเป็นดังนี้และไอคอนตัวเรียกใช้งานของคุณเรียกว่าic_launcher.png:

[Project Root]
  -[Module]
    -src
      -main
        -res
          -drawable-*
            -ic_launcher.png

จากนั้นในการเพิ่มไอคอนแยกต่างหากสำหรับประเภทการดีบักคุณเพิ่ม:

[Project Root]
  -[Module]
    -src
      -main
        -res
          -drawable-*
            -ic_launcher.png
      -debug
        -res
          -drawable-*
            -ic_launcher.png

จากนั้นเมื่อคุณสร้างภายใต้ประเภทการดีบักบิวด์จะใช้ ic_launcher ที่พบในโฟลเดอร์ดีบัก


คุณไม่จำเป็นต้องระบุโฟลเดอร์ดีบักเพิ่มเติมด้วยการประกาศ sourceSets หรือไม่?
ncoronges

1
@ncoronges ฉันไม่ได้ ดูเหมือนว่าเนื่องจากดีบักเป็นชนิดบิลด์ในตัวชุดซอร์สสำหรับมันก็มีอยู่ในตัวเช่นกัน
InsanityOnABun

1
@Scott มันใช้ได้กับฉันโดยใช้ 'debug' ถ้าฉันใส่ไอคอนของฉันในแต่ละโฟลเดอร์ที่วาดได้ เช่น drawable-mdpi, drawable-hdpi เป็นต้นฉันไม่ต้องการทรัพยากรหรือโค้ดอื่นใดในโฟลเดอร์ดีบัก
เสียงคำราม

3
ใช้งานได้เหมือนมีเสน่ห์ ต้องคัดลอกไดเรกทอรี mipmap ทั้งหมดในโฟลเดอร์ debug
Amit Bhandari

1
จะมีชื่อแอปอื่นได้อย่างไร?
DKV

95

นี่เป็นแนวทางที่มีประโยชน์แม้ว่าจะมีข้อเสียที่สำคัญ ... ตัวเรียกใช้งานทั้งสองจะถูกใส่ลงใน apk ของคุณ - Bartek Lipinski

วิธีที่ดีกว่า: คำตอบของ InsanityOnABun

AndroidManifest.xml

<manifest 

    ...
        <application
        android:allowBackup="true"
        android:icon="${appIcon}"
        android:roundIcon="${appIconRound}"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

    ...

    </application>

</manifest>

build.gradle

android {

    ...
        productFlavors{
        Test{
            versionName "$defaultConfig.versionName" + ".test"
            resValue "string", "app_name", "App-Test"
            manifestPlaceholders = [
                    appIcon: "@mipmap/ic_launcher_test",
                    appIconRound: "@mipmap/ic_launcher_test_round"
            ]
        }

        Product{
            resValue "string", "app_name", "App"
            manifestPlaceholders = [
                    appIcon: "@mipmap/ic_launcher",
                    appIconRound: "@mipmap/ic_launcher_round"
            ]
        }
    }
}

URL ของ Github: สร้างแอปหลายเวอร์ชันด้วย Gradle


1
นี่เป็นแนวทางที่มีประโยชน์แม้ว่าจะมีข้อเสียที่สำคัญ ... ตัวเรียกใช้งานทั้งสองจะถูกใส่ลงใน apk ของคุณ
Bartek Lipinski

-_- # มันเป็นปัญหาฉันอัปเดตวิธีที่ดีกว่า: -> stackoverflow.com/a/22876224/703225
qinmiao

2
เหตุใดจึงเป็นข้อเสียที่สำคัญ มันดูไม่สำคัญเกินไปสำหรับฉันและเป็นวิธีแก้ปัญหาที่ดีและสะอาด
luky

2
คำถามที่สอง @ luky ทำไมถึงเป็นข้อเสีย? ฉันคิดว่าการเพิ่มไดเรกทอรีระดับบนสุดเพิ่มเติม (ฉันมีรูปแบบการสร้างที่แตกต่างกันสี่แบบในโครงการของฉัน) นั้นสะอาดน้อยกว่าการใช้ตัวยึดรายการ โดยเฉพาะอย่างยิ่งเมื่อไดเรกทอรีเหล่านั้นมีเพียงไอคอนเดียว
GregSantulli

หากคุณต้องการใช้วิธีนี้และหยุดเพิ่มไอคอนทั้งสองลงใน APK ที่ใช้งานจริงคุณสามารถตั้งค่าmanifestPlaceholdersเฉพาะในขั้นตอนการดำเนินการหรือเบื้องหลังและifคำสั่ง ฉันกำลังทำสิ่งนี้เพราะฉันมีประเภทการสร้างที่ไม่ใช่การผลิต 1 รายการที่สามารถมีไอคอนที่แตกต่างกันได้สองไอคอน (และฉันไม่ต้องการให้ประเภทงานสร้างทั้งหมดมีความแตกต่างเพียง 1 อย่างกับอีกประเภทหนึ่ง)
Nahuel Barrios

12

คุณสามารถระบุไอคอนในไฟล์ AndroidManifest.xml บางส่วนของรสชาติผลิตภัณฑ์ได้เช่นกัน:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools">
    <application
        tools:replace="android:icon"
        android:icon="@drawable/alternative_icon" />
</manifest>

สิ่งนี้จะเขียนทับไอคอนที่คุณระบุใน AndroidManifest.xml ดั้งเดิม


4
ตรวจสอบคำถาม "มีวิธีใดบ้างในการทำเช่นนี้ผ่านประเภทการสร้างโดยไม่เข้ากับรสชาติของผลิตภัณฑ์ "
InsanityOnABun

4
แม้ว่าจะไม่เป็นไปตามที่ถาม แต่ก็ช่วยฉันได้มาก! ~ ใช้รสชาติ ~
Flummox - อย่าชั่วร้าย SE

2
วิธีที่ดีที่สุดหากคุณมีไฟล์ Manifest เฉพาะอยู่แล้ว
Zax

นี่เป็นวิธีแก้ปัญหาเดียวที่ฉันเคยเห็นมาก่อนซึ่งคุณสามารถรักษาชื่อที่ไม่ซ้ำกันสำหรับไอคอนตัวเรียกใช้งานได้ .. เทียบกับการมีเวอร์ชันมากกว่า 10 เวอร์ชันic_launcher.pngโดยต้องรู้ว่าอันไหนคือที่ตั้งหรือเปิดจริงๆ (ไม่ใช่อย่างนั้น ดี). ฉันไม่รู้ว่าการขยายประเภทนี้สำหรับไฟล์ manifestนั้นเป็นไปได้ด้วยซ้ำไม่เคยเห็นมันกล่าวถึงที่อื่นใน SO หรืออย่างอื่นมาก่อนที่นี่ สวยหรูแน่นอน
Gene Bo

6

สำหรับการรับไอคอนที่แตกต่างกันในขณะที่ใช้รสชาติที่แตกต่างกันโดยมีหลายมิติเช่น:

flavorDimensions "color", "size"
productFlavors {
    black {
        dimension "color"
    }
    white {
        dimension "color"
    }

    big {
        dimension "size"
    }
    small {
        dimension "size"
    }
}

สิ่งนี้สามารถทำได้โดย:

ขั้นแรกวางทรัพยากรการดีบักไว้ในโฟลเดอร์แยกต่างหากเช่น:

src/blackDebug/res
src/whiteDebug/res

ประการที่สองให้ใส่คีย์ที่มีขนาดรสชาติที่หลากหลายคือชื่อชุดแหล่งที่มาต้องมีส่วนผสมของรสชาติที่เป็นไปได้ทั้งหมดแม้ว่ามิติข้อมูลเหล่านี้บางส่วนจะไม่มีผลกับไอคอนก็ตาม

sourceSets {
    // Override the icons in debug mode
    blackBigDebug.res.srcDir 'src/blackDebug/res'
    blackSmallDebug.res.srcDir 'src/blackDebug/res'
    whiteBigDebug.res.srcDir 'src/whiteDebug/res'
    whiteSamllDebug.res.srcDir 'src/whiteDebug/res'
}

เพื่อให้ชัดเจนสิ่งต่อไปนี้จะใช้ไม่ได้เมื่อใช้งานหลายมิติ:

sourceSets {
    // Override the icons in debug mode
    blackDebug.res.srcDir 'src/blackDebug/res'
    whiteDebug.res.srcDir 'src/whiteDebug/res'
}

ไม่แน่ใจว่าวิธีนี้จะช่วยได้อย่างไรเนื่องจากมีการประกาศไอคอนเปิดตัวในไฟล์รายการ คุณสามารถแก้ไขปัญหานั้นได้หรือไม่?
David Rector

3
มีการประกาศชื่อทรัพยากรในรายการ แต่คุณสามารถมีไอคอนที่แตกต่างกันที่มีชื่อไฟล์เดียวกันในโฟลเดอร์เฉพาะรสชาติต่างๆตามที่อธิบายไว้ในโพสต์ของฉัน
Jose Gómez

0

วิธีแก้ปัญหาทีละขั้นตอนรวมถึงการแทนที่ mipmap-anydpi-v26 และเก็บไฟล์สำหรับมิติทั้งหมด:

ขั้นแรกให้กำหนดใน build.gradle (Module: app) ประเภทการสร้างของคุณใน android -> buildTypes -> debug, internal, etc

ในลำดับชั้นของโปรเจ็กต์ด้านล่าง Android ให้คลิกขวาที่แอพ -> ใหม่ -> Image Asset -> ใน Path เลือกไอคอนของคุณ -> การเปลี่ยนแปลงอื่น ๆ ใน Background Layer และ Legacy -> Next -> ใน Res Directory เลือกประเภทการสร้างที่คุณต้องการ ( ดีบักภายในหลัก ฯลฯ ) -> เสร็จสิ้น

ด้วยวิธีนี้ไอคอนจะแทนที่ไอคอนเก่าทั้งหมดที่คุณมี

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.