เลือกคลังอย่างชาญฉลาด

หากต้องการเปิดใช้การเพิ่มประสิทธิภาพแอป คุณต้องไลบรารีที่เข้ากันได้กับการเพิ่มประสิทธิภาพ Android หากไม่ได้กําหนดค่าไลบรารีสําหรับการเพิ่มประสิทธิภาพ Android เช่น หากใช้การสะท้อนโดยไม่รวมกฎการเก็บรักษาที่เกี่ยวข้อง ไลบรารีดังกล่าวอาจไม่เหมาะกับแอป Android หน้านี้จะอธิบายสาเหตุที่ไลบรารีบางรายการเหมาะกับการเพิ่มประสิทธิภาพแอปมากกว่า และแสดงเคล็ดลับทั่วไปเพื่อช่วยคุณเลือก

โปรดใช้ codegen แทนการสะท้อน

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

ดูข้อมูลเพิ่มเติมเกี่ยวกับ codegen เทียบกับการแสดงผลได้ที่การเพิ่มประสิทธิภาพสำหรับผู้เขียนไลบรารี

เคล็ดลับทั่วไปเมื่อเลือกไลบรารี

ใช้เคล็ดลับเหล่านี้เพื่อให้แน่ใจว่าไลบรารีของคุณเข้ากันได้กับการเพิ่มประสิทธิภาพแอป

ตรวจสอบปัญหาการเพิ่มประสิทธิภาพ

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

  • ไลบรารี AndroidX และไลบรารีอื่นๆ เช่น Hilt ทำงานร่วมกับการเพิ่มประสิทธิภาพแอปได้ดี เนื่องจากใช้ codegen แทนการสะท้อน เมื่อใช้การสะท้อนกลับ ก็จะระบุกฎการเก็บรักษาขั้นต่ำเพื่อเก็บเฉพาะโค้ดที่จําเป็น
  • ไลบรารีการจัดรูปแบบข้อมูลมักใช้การสะท้อนกลับเพื่อหลีกเลี่ยงโค้ดที่ซ้ำกันเมื่อสร้างอินสแตนซ์หรือจัดรูปแบบข้อมูลออบเจ็กต์ มองหาไลบรารีที่ใช้ codegen เพื่อหลีกเลี่ยงปัญหาเหล่านี้แทนแนวทางที่อิงตามการสะท้อน (เช่น Gson สำหรับ JSON) เช่น ใช้การแปลงข้อมูลของ Kotlin แทน
  • คุณควรหลีกเลี่ยงการใช้ไลบรารีที่มีกฎการเก็บทั่วทั้งแพ็กเกจ หากเป็นไปได้ กฎการเก็บรักษาทั้งแพ็กเกจช่วยแก้ไขข้อผิดพลาดได้ แต่ควรปรับแต่งกฎการเก็บรักษาแบบกว้างเพื่อเก็บเฉพาะโค้ดที่จำเป็นเท่านั้น ดูข้อมูลเพิ่มเติมได้ที่ใช้การเพิ่มประสิทธิภาพทีละน้อย

เปิดใช้การเพิ่มประสิทธิภาพหลังจากเพิ่มคลังใหม่

เมื่อเพิ่มคลังใหม่ ให้เปิดใช้การเพิ่มประสิทธิภาพในภายหลังและตรวจสอบว่ามีข้อผิดพลาดหรือไม่ หากมีข้อผิดพลาด ให้มองหาทางเลือกอื่นสำหรับคลังนั้นหรือเขียนกฎการคงไว้ หากคลังเข้ากันไม่ได้กับการเพิ่มประสิทธิภาพ ให้รายงานข้อบกพร่องเกี่ยวกับคลังนั้น

กฎเป็นส่วนเสริม

โปรดทราบว่ากฎการเก็บรักษาเป็นส่วนเสริม ซึ่งหมายความว่าคุณจะนํากฎบางอย่างที่ไลบรารีที่อ้างอิงมีออกไม่ได้ และอาจส่งผลต่อการคอมไพล์ส่วนอื่นๆ ของแอป เช่น หากไลบรารีมีกฎในการปิดใช้การเพิ่มประสิทธิภาพโค้ด กฎนั้นจะปิดใช้การเพิ่มประสิทธิภาพสําหรับทั้งโปรเจ็กต์

ตรวจสอบการใช้การสะท้อน (ขั้นสูง)

คุณอาจบอกได้ว่าไลบรารีใช้การสะท้อนหรือไม่จากการตรวจสอบโค้ด หากไลบรารีใช้การสะท้อน ให้ตรวจสอบว่ามีการระบุกฎการเก็บรักษาที่เกี่ยวข้อง ไลบรารีอาจใช้การสะท้อนกลับหากมีลักษณะการทำงานต่อไปนี้

  • ใช้คลาสหรือเมธอดจากแพ็กเกจ 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 เป็นไลบรารีการจัดรูปแบบข้อมูล (Serialization) ที่มักทำให้เกิดปัญหากับการเพิ่มประสิทธิภาพแอปเนื่องจากใช้การสะท้อน (Reflection) อย่างมาก ข้อมูลโค้ดต่อไปนี้แสดงวิธีใช้ 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 ในส่วนใดเลย ระบบอาจเปลี่ยนชื่อช่องหรือนําตัวสร้างที่ไม่ดูเหมือนว่าจะใช้แล้วออก ซึ่งทําให้แอปขัดข้อง หากคุณใช้ไลบรารีอื่นๆ ในลักษณะที่คล้ายกัน คุณควรตรวจสอบว่าไลบรารีเหล่านั้นจะไม่รบกวนการเพิ่มประสิทธิภาพของแอป และหลีกเลี่ยงหากรบกวน

โปรดทราบว่าทั้ง Room และ Hilt ต่างก็สร้างประเภทที่กําหนดโดยแอป แต่ใช้ codegen เพื่อหลีกเลี่ยงการใช้การสะท้อน