เมื่อเปิดใช้การเพิ่มประสิทธิภาพแอป ลักษณะการทำงานเริ่มต้นของเครื่องมือเพิ่มประสิทธิภาพจะ แตกต่างกันไปตาม 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/my.package.keep.xml ไฟล์ keep มีคอมโพเนนต์ต่อไปนี้
- แท็ก
<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" />
การระบุทรัพยากรที่จะทิ้งอาจดูเหมือนไม่จำเป็นในเมื่อคุณสามารถลบทรัพยากรเหล่านั้นได้ แต่การทิ้งทรัพยากรอาจมีประโยชน์เมื่อใช้ตัวแปรของบิลด์
กำหนดเป้าหมายตัวแปรของบิลด์ที่เฉพาะเจาะจง
หากต้องการนำทรัพยากรออกในตัวแปรบิลด์บางรายการเท่านั้น ให้ใส่ทรัพยากรทั้งหมดลงในไดเรกทอรีโปรเจ็กต์ทั่วไป จากนั้นสร้างไฟล์ my.package.build.variant.keep.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) จะผสานทรัพยากรที่มีชื่อเหมือนกัน เช่น Drawables ที่มีชื่อเดียวกันซึ่งอยู่ในโฟลเดอร์ทรัพยากรต่างๆ
ลักษณะการทำงานนี้ไม่ได้ควบคุมโดยพร็อพเพอร์ตี้ shrinkResources และปิดใช้ไม่ได้เนื่องจากลักษณะการทำงานนี้จำเป็นต่อการหลีกเลี่ยงข้อผิดพลาดเมื่อทรัพยากรหลายรายการมีชื่อที่โค้ดของคุณอ้างอิง
การผสานทรัพยากรจะเกิดขึ้นก็ต่อเมื่อไฟล์อย่างน้อย 2 ไฟล์มีชื่อทรัพยากร ประเภท และตัวระบุเหมือนกัน AGP จะเลือกไฟล์ที่ระบุว่าเป็นตัวเลือกที่ดีที่สุดในบรรดาไฟล์ที่ซ้ำกัน (โดยอิงตามลำดับความสำคัญที่อธิบายไว้ด้านล่าง) และส่งเฉพาะทรัพยากรนั้นไปยัง AAPT เพื่อเผยแพร่ในอาร์ติแฟกต์บิลด์สุดท้าย
AGP จะค้นหาทรัพยากรที่ซ้ำกันในตำแหน่งต่อไปนี้
- ทรัพยากรหลักที่เชื่อมโยงกับชุดซอร์สหลัก ซึ่งโดยทั่วไปจะอยู่ใน
src/main/res/ - การวางซ้อนตัวแปรจากประเภทบิลด์และรสชาติบิลด์
- ทรัพยากร Dependency ของโปรเจ็กต์ไลบรารี
AGP จะผสานทรัพยากรที่ซ้ำกันตามลำดับความสำคัญแบบลดหลั่นต่อไปนี้
ตัวอย่างเช่น หากทรัพยากรที่ซ้ำกันปรากฏในทั้งทรัพยากรหลักและรสชาติบิลด์ Gradle จะเลือกทรัพยากรในรสชาติบิลด์
หากทรัพยากรที่เหมือนกันปรากฏในชุดซอร์สเดียวกัน 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 จึงเข้าถึงได้ และหากค้นหาขึ้นไป คุณจะเห็นทรัพยากรที่แสดงอยู่ใต้หัวข้อ The root reachable resources are: ใน 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 เพื่อแจ้งให้ระบบบิลด์นำทรัพยากรออก