ปรับแต่งทรัพยากรที่จะเก็บไว้

เมื่อเปิดใช้การเพิ่มประสิทธิภาพแอป ลักษณะการทำงานเริ่มต้นของเครื่องมือเพิ่มประสิทธิภาพจะ แตกต่างกันสำหรับ R8 เวอร์ชันต่างๆ

  • เมื่อใช้ DSL ที่อัปเดตแล้วซึ่งพร้อมใช้งานใน AGP 9.3 ขึ้นไป ระบบจะเปิดใช้การลดขนาดทรัพยากรโดยค่าเริ่มต้นเมื่อเปิดใช้การเพิ่มประสิทธิภาพ โปรดทราบว่าระบบยังคงรองรับ DSL เดิม ซึ่งต้องมีการเพิ่มประสิทธิภาพโค้ดและทรัพยากรเพื่อ เปิดใช้โดยเฉพาะ
  • สำหรับเวอร์ชันก่อน AGP 9.3 การตั้งค่า isShrinkResources = true จะสั่งให้ตัวเพิ่มประสิทธิภาพนำทรัพยากรที่ไม่ได้ใช้ออก ซึ่งจะช่วย ลดขนาดแอป การย่อทรัพยากรจะทำงานร่วมกับ การย่อโค้ดเท่านั้น ดังนั้นหากคุณเพิ่มประสิทธิภาพทรัพยากร ให้ตั้งค่า isMinifyEnabled = true ด้วย

AGP 9.3 ขึ้นไป (Kotlin)

buildTypes {
    release {
        optimization {
            enable = true // Enables code and resource optimizations.
        }
    }
}

AGP 9.3 ขึ้นไป (Groovy)

buildTypes {
    release {
        optimization {
            enable = true // Enables code and resource optimizations.
        }
    }
}

DSL เดิม (Kotlin)

buildTypes {
    release {
        isMinifyEnabled = true
        isShrinkResources = true
        ...
    }
}

DSL เดิม (Groovy)

buildTypes {
    release {
        minifyEnabled = true
        shrinkResources = true
        ...
    }
}

หากต้องการเก็บหรือทิ้งทรัพยากรที่เฉพาะเจาะจง ให้สร้างไฟล์ XML keep ใน ทรัพยากรของโปรเจ็กต์ เช่น res/raw/keep_my_package.xml ไฟล์เก็บ มีคอมโพเนนต์ต่อไปนี้

  • แท็ก <resources> - มีองค์ประกอบทรัพยากรย่อยทั้งหมดและแอตทริบิวต์ keep/discard
  • แอตทริบิวต์ tools:keep — รับรายการชื่อทรัพยากรที่คั่นด้วยคอมมา ซึ่งระบุทรัพยากรที่จะเก็บไว้
  • แอตทริบิวต์ tools:discard — รับรายการชื่อทรัพยากรที่คั่นด้วยคอมมา ซึ่งระบุทรัพยากรที่จะทิ้ง

ใช้อักขระดอกจันเป็นไวลด์การ์ดเพื่ออ้างอิงทรัพยากรหลายรายการใน โฟลเดอร์เดียวกัน เช่น

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*"
    tools:discard="@layout/unused2" />

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

กำหนดเป้าหมายตัวแปรบิลด์ที่เฉพาะเจาะจง

หากต้องการนำทรัพยากรออกในเฉพาะบางตัวแปรบิลด์ ให้ใส่ทรัพยากรทั้งหมดลงในไดเรกทอรีโปรเจ็กต์ทั่วไป จากนั้นสร้างไฟล์ keep_my_package_build_variant.xml ที่แตกต่างกันสำหรับแต่ละตัวแปรบิลด์ในไดเรกทอรีทรัพยากรของตัวแปรบิลด์ ในไฟล์ keep ให้ระบุทรัพยากรที่จะนำออกด้วยตนเองเมื่อ ทรัพยากรที่กำหนดดูเหมือนจะใช้ในโค้ด (และด้วยเหตุนี้จึงไม่ถูกเครื่องย่อขนาดนำออก) แต่คุณทราบว่าจริงๆ แล้วจะไม่ใช้สำหรับตัวแปรบิลด์ที่กำหนด

นำแหล่งข้อมูลสำรองที่ไม่ได้ใช้ออก

เครื่องมือเพิ่มประสิทธิภาพจะนำเฉพาะทรัพยากรที่โค้ดแอปไม่ได้อ้างอิงออก ซึ่งหมายความว่าเครื่องมือเพิ่มประสิทธิภาพจะไม่นำทรัพยากรทางเลือกสำหรับการกำหนดค่าอุปกรณ์ต่างๆ ออก

ใช้พร็อพเพอร์ตี้ resConfigs Android Gradle ในไฟล์ build.gradle โมดูลของแอปเพื่อนำไฟล์ทรัพยากรทางเลือกที่แอปไม่ต้องการออก

เช่น หากคุณใช้ไลบรารีที่มีทรัพยากรภาษา (เช่น บริการ Google Play) แอปของคุณจะมีสตริงภาษาที่แปลทั้งหมดสำหรับข้อความในไลบรารีเหล่านั้น ไม่ว่าส่วนอื่นๆ ของแอปจะแปลเป็นภาษาเดียวกันหรือไม่ก็ตาม หากต้องการเก็บเฉพาะภาษาที่แอปของคุณรองรับอย่างเป็นทางการ ให้ระบุภาษาเหล่านั้นโดยใช้พร็อพเพอร์ตี้ resConfigs ระบบจะนำทรัพยากรสำหรับภาษาที่ไม่ได้ระบุออก

ข้อมูลโค้ดต่อไปนี้แสดงวิธีกำหนดทรัพยากรภาษาให้เป็นภาษาอังกฤษและฝรั่งเศสเท่านั้น

android {
    defaultConfig {
        ...
        resourceConfigurations.addAll(listOf("en", "fr"))
    }
}

หรือ

android {
    defaultConfig {
        ...
        resConfigs "en", "fr"
    }
}

เมื่อเผยแพร่แอปโดยใช้รูปแบบ Android App Bundle (AAB) ระบบจะดาวน์โหลดเฉพาะภาษาที่กำหนดค่าไว้ในอุปกรณ์ของผู้ใช้เมื่อผู้ใช้ ติดตั้งแอปโดยค่าเริ่มต้น ในทำนองเดียวกัน ระบบจะรวมเฉพาะทรัพยากรที่ตรงกับความหนาแน่นของหน้าจออุปกรณ์ และไลบรารีเนทีฟที่ตรงกับ ABI ของอุปกรณ์ไว้ในการดาวน์โหลด ดูข้อมูลเพิ่มเติมได้ที่เปิดใช้หรือปิดใช้ประเภท APK การกำหนดค่า

สำหรับแอปเดิมที่เผยแพร่ด้วย APK (สร้างก่อนเดือนสิงหาคม 2021) คุณสามารถ ปรับแต่งความหนาแน่นของหน้าจอหรือทรัพยากร ABI เพื่อรวมไว้ใน APK ได้โดย สร้าง APK หลายรายการที่กำหนดเป้าหมายการกำหนดค่าอุปกรณ์ที่แตกต่างกัน

หลีกเลี่ยงความขัดแย้งเมื่อผสานทรัพยากร

โดยค่าเริ่มต้น ปลั๊กอิน Android Gradle (AGP) จะผสานทรัพยากรที่มีชื่อเหมือนกัน เช่น Drawable ที่มีชื่อเดียวกันซึ่งอยู่ในโฟลเดอร์ทรัพยากรที่แตกต่างกัน ลักษณะการทำงานนี้ไม่ได้ควบคุมโดยพร็อพเพอร์ตี้ shrinkResources และปิดใช้ไม่ได้เนื่องจากลักษณะการทำงานนี้จำเป็นต่อการหลีกเลี่ยงข้อผิดพลาดเมื่อทรัพยากรหลายรายการมีชื่อที่โค้ดของคุณอ้างอิง

การผสานทรัพยากรจะเกิดขึ้นก็ต่อเมื่อไฟล์อย่างน้อย 2 ไฟล์ใช้ชื่อ ประเภท และตัวระบุทรัพยากรเดียวกัน AGP จะเลือกไฟล์ที่ระบุว่าดีที่สุด ในบรรดาไฟล์ที่ซ้ำกัน (อิงตามลำดับความสำคัญที่อธิบายไว้ด้านล่าง) และ ส่งเฉพาะทรัพยากรนั้นไปยัง AAPT เพื่อจัดจำหน่ายในอาร์ติแฟกต์บิลด์สุดท้าย

AGP จะมองหาทรัพยากรที่ซ้ำกันในตำแหน่งต่อไปนี้

  • โดยทั่วไปแล้ว แหล่งข้อมูลหลักที่เชื่อมโยงกับชุดซอร์สหลักจะอยู่ใน src/main/res/
  • การซ้อนทับตัวแปรจากประเภทบิลด์และบิลด์ Flavor
  • ทรัพยากร Dependency ของโปรเจ็กต์ไลบรารี

AGP จะผสานทรัพยากรที่ซ้ำกันตามลำดับความสำคัญแบบเรียงซ้อนต่อไปนี้

Dependencies → Main → Build flavor → Build type

เช่น หากมีทรัพยากรที่ซ้ำกันปรากฏทั้งในทรัพยากรหลักและ Build Flavor Gradle จะเลือกทรัพยากรใน Build Flavor

หากทรัพยากรที่เหมือนกันปรากฏในชุดซอร์สเดียวกัน Gradle จะผสานรวมทรัพยากรเหล่านั้นไม่ได้ และจะแสดงข้อผิดพลาดในการผสานรวมทรัพยากร ปัญหานี้อาจเกิดขึ้นหากคุณกำหนดชุดแหล่งข้อมูลหลายชุดในพร็อพเพอร์ตี้ sourceSet ของไฟล์ build.gradle โมดูล เช่น หากทั้ง src/main/res/ และ src/main/res2/ มีทรัพยากรที่เหมือนกัน

แก้ปัญหาการลดขนาดทรัพยากร

เมื่อลดขนาดทรัพยากร หน้าต่างบิลด์จะแสดงข้อมูลสรุปของทรัพยากรที่นำออกจากแอป (คลิกสลับมุมมองทางด้านซ้ายของหน้าต่างเพื่อแสดงเอาต์พุตข้อความโดยละเอียดจาก Gradle) เช่น

:android:shrinkDebugResources
Removed unused resources: Resource data reduced from 2570KB to 1711KB: Removed 33%
:android:validateDebugSigning

นอกจากนี้ Gradle ยังสร้างไฟล์การวินิจฉัยชื่อ resources.txt ใน <module-name>/build/outputs/mapping/release/ (โฟลเดอร์เดียวกับไฟล์เอาต์พุตของ ProGuard ) ไฟล์นี้มีรายละเอียด เช่น ทรัพยากรใดอ้างอิงทรัพยากรอื่น และทรัพยากรใดที่ใช้หรือนำออก

เช่น หากต้องการทราบว่าเหตุใด @drawable/ic_plus_anim_016 ยังคงอยู่ในแอป ให้เปิดไฟล์ resources.txt แล้วค้นหาชื่อไฟล์นั้น คุณอาจพบว่า มีการอ้างอิงจากแหล่งข้อมูลอื่น

16:25:48.005 [QUIET] [system.out] @drawable/add_schedule_fab_icon_anim : reachable=true
16:25:48.009 [QUIET] [system.out] @drawable/ic_plus_anim_016

ตอนนี้คุณต้องทราบว่าทำไม @drawable/add_schedule_fab_icon_anim จึงเข้าถึงได้ และหากค้นหาขึ้นไป คุณจะเห็นแหล่งข้อมูลที่แสดงในส่วนหัวแหล่งข้อมูลรูทที่เข้าถึงได้คือใน resources.txt

ซึ่งหมายความว่ามีการอ้างอิงโค้ดถึง add_schedule_fab_icon_anim นั่นคือระบบพบรหัส R.drawable ในโค้ดที่เข้าถึงได้

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

10:32:50.590 [QUIET] [system.out] Marking drawable:ic_plus_anim_016:2130837506
    used because its format-string matches string pool constant ic_plus_anim_%1$d.

หากเห็นสตริงใดสตริงหนึ่งต่อไปนี้และมั่นใจว่าไม่ได้ใช้สตริงเพื่อโหลดทรัพยากรที่ระบุแบบไดนามิก ให้ใช้แอตทริบิวต์ tools:discard ในไฟล์ Keep เพื่อแจ้งให้ระบบบิลด์นำทรัพยากรออก