หากต้องการเปิดใช้การเพิ่มประสิทธิภาพแอป คุณต้องใช้ไลบรารีที่เข้ากันได้กับการเพิ่มประสิทธิภาพ Android หากไม่ได้กำหนดค่าไลบรารีสำหรับการเพิ่มประสิทธิภาพ Android เช่น หากใช้การสะท้อนโดยไม่ได้รวมกฎการเก็บรักษาที่เกี่ยวข้อง ไลบรารีนั้นอาจไม่เหมาะกับแอป Android หน้านี้จะอธิบายเหตุผลที่ไลบรารีบางรายการเหมาะกับการเพิ่มประสิทธิภาพแอปมากกว่า และให้เคล็ดลับทั่วไปที่จะช่วยคุณเลือก
ต้องการใช้ Codegen มากกว่าการสะท้อน
โดยทั่วไป คุณควรเลือกไลบรารีที่ใช้การสร้างโค้ด (codegen) แทนการสะท้อน ด้วย Codegen ตัวเพิ่มประสิทธิภาพจะระบุได้ง่ายขึ้น ว่าโค้ดใดที่ใช้จริงในรันไทม์และโค้ดใดที่นำออกได้ การบอกว่าไลบรารีใช้ Codegen หรือ Reflection อาจเป็นเรื่องยาก แต่ก็มีสัญญาณบางอย่างที่ช่วยได้ โปรดดูเคล็ดลับเพื่อขอความช่วยเหลือ
ดูข้อมูลเพิ่มเติมเกี่ยวกับ Codegen กับ Reflection ได้ที่การเพิ่มประสิทธิภาพสำหรับผู้เขียนไลบรารี
เคล็ดลับทั่วไปเมื่อเลือกไลบรารี
ใช้เคล็ดลับเหล่านี้เพื่อให้แน่ใจว่าไลบรารีของคุณเข้ากันได้กับการเพิ่มประสิทธิภาพแอป
ตรวจสอบปัญหาการเพิ่มประสิทธิภาพ
เมื่อพิจารณาใช้ไลบรารีใหม่ ให้ดูที่เครื่องมือติดตามปัญหาของไลบรารีและการสนทนาออนไลน์เพื่อตรวจสอบว่ามีปัญหาที่เกี่ยวข้องกับการลดขนาดหรือการกำหนดค่าการเพิ่มประสิทธิภาพแอปหรือไม่ หากมี คุณควรลองมองหา ห้องสมุดทางเลือก โปรดทราบว่า
- ไลบรารี AndroidX และไลบรารีต่างๆ เช่น Hilt ทำงานได้ดีกับการเพิ่มประสิทธิภาพแอป เนื่องจากใช้ Codegen แทนการสะท้อน เมื่อใช้การสะท้อน นักพัฒนาแอปจะระบุกฎการเก็บรักษาขั้นต่ำเพื่อเก็บเฉพาะโค้ดที่จำเป็น
- ไลบรารีการซีเรียลไลซ์มักใช้การสะท้อนเพื่อหลีกเลี่ยงโค้ดสำเร็จรูป เมื่อสร้างอินสแตนซ์หรือซีเรียลไลซ์ออบเจ็กต์ แทนที่จะใช้วิธีการที่อิงตามการสะท้อน (เช่น Gson สำหรับ JSON) ให้มองหาไลบรารีที่ใช้ Codegen เพื่อ หลีกเลี่ยงปัญหาเหล่านี้ เช่น ใช้ Kotlin Serialization แทน
- ควรหลีกเลี่ยงการใช้ไลบรารีที่มีกฎการเก็บรักษาทั่วทั้งแพ็กเกจหากเป็นไปได้ กฎการเก็บรักษาระดับแพ็กเกจจะช่วยแก้ไขข้อผิดพลาดได้ แต่ในที่สุดควรกำหนดกฎการเก็บรักษาแบบกว้างให้เก็บเฉพาะโค้ดที่จำเป็นเท่านั้น ดูข้อมูลเพิ่มเติมได้ที่ใช้การเพิ่มประสิทธิภาพทีละขั้น
- ไลบรารีไม่ควรบังคับให้คุณคัดลอกและวางกฎการเก็บจากเอกสารประกอบลงในไฟล์ในโปรเจ็กต์ โดยเฉพาะกฎการเก็บระดับแพ็กเกจ กฎเหล่านี้กลายเป็นภาระในการบำรุงรักษาสำหรับนักพัฒนาแอปในระยะยาว และยากที่จะเพิ่มประสิทธิภาพและเปลี่ยนแปลงเมื่อเวลาผ่านไป
เปิดใช้การเพิ่มประสิทธิภาพหลังจากเพิ่มคลังใหม่
เมื่อเพิ่มไลบรารีใหม่ ให้เปิดใช้การเพิ่มประสิทธิภาพในภายหลังและตรวจสอบว่ามีข้อผิดพลาดหรือไม่ หากมีข้อผิดพลาด ให้มองหาทางเลือกอื่นสำหรับไลบรารีนั้นหรือเขียน กฎการเก็บ หากไลบรารีไม่รองรับการเพิ่มประสิทธิภาพ ให้รายงานข้อบกพร่องของไลบรารีนั้น
กฎเป็นส่วนเสริม
โปรดทราบว่ากฎการเก็บรักษาเป็นส่วนเสริม ซึ่งหมายความว่าระบบจะนำกฎบางอย่างที่การอ้างอิงไลบรารีรวมอยู่ด้วยออกไม่ได้ และอาจส่งผลต่อการคอมไพล์ส่วนอื่นๆ ของแอป ตัวอย่างเช่น หากไลบรารีมีกฎเพื่อปิดใช้การเพิ่มประสิทธิภาพโค้ด กฎดังกล่าวจะปิดใช้การเพิ่มประสิทธิภาพสำหรับทั้งโปรเจ็กต์
ตรวจสอบการใช้การสะท้อน (ขั้นสูง)
คุณอาจบอกได้ว่าไลบรารีใช้การสะท้อนหรือไม่จากการตรวจสอบโค้ด หากไลบรารีใช้การสะท้อน ให้ตรวจสอบว่ามีกฎการเก็บรักษาที่เชื่อมโยงกัน ไลบรารีอาจใช้การสะท้อนหากทำสิ่งต่อไปนี้
- ใช้คลาสหรือเมธอดจากแพ็กเกจ
kotlin.reflectหรือjava.lang.reflect - ใช้ฟังก์ชัน
Class.forNameหรือclassLoader.getClass - อ่านคำอธิบายประกอบที่รันไทม์ เช่น หากจัดเก็บค่าคำอธิบายประกอบ
โดยใช้
val value = myClass.getAnnotation()หรือval value = myMethod.getAnnotation()แล้วทำบางอย่างกับvalue เรียกใช้เมธอดโดยใช้ชื่อเมธอดเป็นสตริง เช่น
// Calls the private `processData` API with reflection myObject.javaClass.getMethod("processData", DataType::class.java) ?.invoke(myObject, data)
กรองกฎการเก็บรักษาที่ไม่ดีออก (ขั้นสูง)
คุณควรหลีกเลี่ยงไลบรารีที่มีกฎการเก็บรักษาโค้ดที่ควรนำออก แต่หากจำเป็นต้องใช้ คุณสามารถกรองกฎออกได้ตามที่แสดงในโค้ดต่อไปนี้
// If you're using AGP 8.4 and higher
buildTypes {
release {
optimization.keepRules {
it.ignoreFrom("com.somelibrary:somelibrary")
}
}
}
// If you're using AGP 7.3-8.3
buildTypes {
release {
optimization.keepRules {
it.ignoreExternalDependencies("com.somelibrary:somelibrary")
}
}
}
กรณีศึกษา: เหตุใด Gson จึงหยุดทำงานเมื่อมีการเพิ่มประสิทธิภาพ
Gson เป็นไลบรารีการซีเรียลไลซ์ที่มักทำให้เกิดปัญหาเกี่ยวกับการเพิ่มประสิทธิภาพแอป
เนื่องจากใช้การสะท้อนอย่างมาก ข้อมูลโค้ดต่อไปนี้แสดงวิธีใช้ Gson โดยทั่วไป ซึ่งอาจทำให้เกิดข้อขัดข้องในรันไทม์ได้ง่าย โปรดทราบว่าเมื่อคุณ
ใช้ Gson เพื่อรับรายการออบเจ็กต์ User คุณจะไม่เรียกใช้ตัวสร้างหรือส่ง
Factory ไปยังฟังก์ชัน fromJson() การสร้างหรือใช้คลาสที่แอปกำหนด
โดยไม่มีสิ่งต่อไปนี้เป็นสัญญาณว่าไลบรารีอาจใช้
การสะท้อนแบบเปิด
- คลาสแอปที่ใช้ไลบรารี หรืออินเทอร์เฟซหรือคลาสมาตรฐาน
- ปลั๊กอินการสร้างโค้ด เช่น KSP
class User(val name: String)
class UserList(val users: List<User>)
// This code runs in debug mode, but crashes when optimizations are enabled
Gson().fromJson("""[{"name":"myname"}]""", User::class.java).toString()
เมื่อ R8 วิเคราะห์โค้ดนี้และไม่พบว่ามีการสร้างอินสแตนซ์ของ UserList หรือ User ที่ใดก็ตาม
R8 จะเปลี่ยนชื่อฟิลด์หรือนำตัวสร้างที่ดูเหมือนจะไม่ได้ใช้
ออก ซึ่งทำให้แอปขัดข้อง หากคุณใช้ไลบรารีอื่นๆ ในลักษณะที่คล้ายกัน
คุณควรตรวจสอบว่าไลบรารีเหล่านั้นจะไม่รบกวนการเพิ่มประสิทธิภาพแอป และหาก
รบกวน ก็ควรหลีกเลี่ยง
โปรดทราบว่าทั้ง Room และ Hilt ต่างก็สร้างประเภทที่แอปกำหนด แต่ใช้ Codegen เพื่อหลีกเลี่ยงการใช้การสะท้อน