เลือกคลังอย่างชาญฉลาด
จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน
บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ
หากต้องการเปิดใช้การเพิ่มประสิทธิภาพแอป คุณต้องไลบรารีที่เข้ากันได้กับการเพิ่มประสิทธิภาพ Android หากไม่ได้กําหนดค่าไลบรารีสําหรับการเพิ่มประสิทธิภาพ Android เช่น หากใช้การสะท้อนโดยไม่รวมกฎการเก็บรักษาที่เกี่ยวข้อง ไลบรารีดังกล่าวอาจไม่เหมาะกับแอป Android หน้านี้จะอธิบายสาเหตุที่ไลบรารีบางรายการเหมาะกับการเพิ่มประสิทธิภาพแอปมากกว่า และแสดงเคล็ดลับทั่วไปเพื่อช่วยคุณเลือก
โปรดใช้ codegen แทนการสะท้อน
โดยทั่วไป คุณควรเลือกไลบรารีที่ใช้การสร้างโค้ด (codegen) แทนการสะท้อน เมื่อใช้ codegen เครื่องมือเพิ่มประสิทธิภาพจะระบุโค้ดที่ใช้จริงในรันไทม์และโค้ดที่นําออกได้ได้ง่ายขึ้น การระบุว่าไลบรารีใช้ codegen หรือ reflection นั้นอาจทำได้ยาก แต่ก็มีสัญญาณบางอย่างที่บ่งบอกได้ โปรดดูเคล็ดลับเพื่อรับความช่วยเหลือ
ดูข้อมูลเพิ่มเติมเกี่ยวกับ codegen เทียบกับการแสดงผลได้ที่การเพิ่มประสิทธิภาพสำหรับผู้เขียนไลบรารี
เคล็ดลับทั่วไปเมื่อเลือกไลบรารี
ใช้เคล็ดลับเหล่านี้เพื่อให้แน่ใจว่าไลบรารีของคุณเข้ากันได้กับการเพิ่มประสิทธิภาพแอป
ตรวจสอบปัญหาการเพิ่มประสิทธิภาพ
เมื่อพิจารณาใช้ไลบรารีใหม่ ให้ตรวจสอบเครื่องมือติดตามปัญหาและการสนทนาออนไลน์ของไลบรารีเพื่อดูว่ามีปัญหาเกี่ยวกับการทำให้เล็กลงหรือการกำหนดค่าการเพิ่มประสิทธิภาพแอปหรือไม่ หากมี คุณควรลองมองหาทางเลือกอื่นสำหรับคลังนั้น โปรดคำนึงถึงสิ่งต่อไปนี้
- ไลบรารี AndroidX และไลบรารีอื่นๆ เช่น Hilt ทำงานร่วมกับการเพิ่มประสิทธิภาพแอปได้ดี เนื่องจากใช้ codegen แทนการสะท้อน เมื่อใช้การสะท้อนกลับ ก็จะระบุกฎการเก็บรักษาขั้นต่ำเพื่อเก็บเฉพาะโค้ดที่จําเป็น
- ไลบรารีการจัดรูปแบบข้อมูลมักใช้การสะท้อนกลับเพื่อหลีกเลี่ยงโค้ดที่ซ้ำกันเมื่อสร้างอินสแตนซ์หรือจัดรูปแบบข้อมูลออบเจ็กต์ มองหาไลบรารีที่ใช้ codegen เพื่อหลีกเลี่ยงปัญหาเหล่านี้แทนแนวทางที่อิงตามการสะท้อน (เช่น Gson สำหรับ JSON) เช่น ใช้การแปลงข้อมูลของ Kotlin แทน
- คุณควรหลีกเลี่ยงการใช้ไลบรารีที่มีกฎการเก็บทั่วทั้งแพ็กเกจ หากเป็นไปได้ กฎการเก็บรักษาทั้งแพ็กเกจช่วยแก้ไขข้อผิดพลาดได้ แต่ควรปรับแต่งกฎการเก็บรักษาแบบกว้างเพื่อเก็บเฉพาะโค้ดที่จำเป็นเท่านั้น ดูข้อมูลเพิ่มเติมได้ที่ใช้การเพิ่มประสิทธิภาพทีละน้อย
เปิดใช้การเพิ่มประสิทธิภาพหลังจากเพิ่มคลังใหม่
เมื่อเพิ่มคลังใหม่ ให้เปิดใช้การเพิ่มประสิทธิภาพในภายหลังและตรวจสอบว่ามีข้อผิดพลาดหรือไม่ หากมีข้อผิดพลาด ให้มองหาทางเลือกอื่นสำหรับคลังนั้นหรือเขียนกฎการคงไว้ หากคลังเข้ากันไม่ได้กับการเพิ่มประสิทธิภาพ ให้รายงานข้อบกพร่องเกี่ยวกับคลังนั้น
กฎเป็นส่วนเสริม
โปรดทราบว่ากฎการเก็บรักษาเป็นส่วนเสริม ซึ่งหมายความว่าคุณจะนํากฎบางอย่างที่ไลบรารีที่อ้างอิงมีออกไม่ได้ และอาจส่งผลต่อการคอมไพล์ส่วนอื่นๆ ของแอป เช่น หากไลบรารีมีกฎในการปิดใช้การเพิ่มประสิทธิภาพโค้ด กฎนั้นจะปิดใช้การเพิ่มประสิทธิภาพสําหรับทั้งโปรเจ็กต์
ตรวจสอบการใช้การสะท้อน (ขั้นสูง)
คุณอาจบอกได้ว่าไลบรารีใช้การสะท้อนหรือไม่จากการตรวจสอบโค้ด
หากไลบรารีใช้การสะท้อน ให้ตรวจสอบว่ามีการระบุกฎการเก็บรักษาที่เกี่ยวข้อง ไลบรารีอาจใช้การสะท้อนกลับหากมีลักษณะการทำงานต่อไปนี้
กรองกฎการเก็บรักษาที่ไม่ถูกต้องออก (ขั้นสูง)
คุณควรหลีกเลี่ยงไลบรารีที่มีกฎ "เก็บ" ซึ่งเก็บโค้ดที่ควรนําออก แต่หากจำเป็นต้องใช้ คุณสามารถกรองกฎออกได้ดังที่แสดงในโค้ดต่อไปนี้
// 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 เพื่อหลีกเลี่ยงการใช้การสะท้อน
ตัวอย่างเนื้อหาและโค้ดในหน้าเว็บนี้ขึ้นอยู่กับใบอนุญาตที่อธิบายไว้ในใบอนุญาตการใช้เนื้อหา Java และ OpenJDK เป็นเครื่องหมายการค้าหรือเครื่องหมายการค้าจดทะเบียนของ Oracle และ/หรือบริษัทในเครือ
อัปเดตล่าสุด 2025-07-27 UTC
[[["เข้าใจง่าย","easyToUnderstand","thumb-up"],["แก้ปัญหาของฉันได้","solvedMyProblem","thumb-up"],["อื่นๆ","otherUp","thumb-up"]],[["ไม่มีข้อมูลที่ฉันต้องการ","missingTheInformationINeed","thumb-down"],["ซับซ้อนเกินไป/มีหลายขั้นตอนมากเกินไป","tooComplicatedTooManySteps","thumb-down"],["ล้าสมัย","outOfDate","thumb-down"],["ปัญหาเกี่ยวกับการแปล","translationIssue","thumb-down"],["ตัวอย่าง/ปัญหาเกี่ยวกับโค้ด","samplesCodeIssue","thumb-down"],["อื่นๆ","otherDown","thumb-down"]],["อัปเดตล่าสุด 2025-07-27 UTC"],[],[],null,["# Choose libraries wisely\n\nTo enable app optimization, you must use libraries that are compatible with\nAndroid optimization. If a library isn't configured for Android optimization---for\nexample, if it uses\n[reflection](https://en.wikipedia.org/wiki/Reflective_programming)\nwithout bundling associated keep rules---it might not be a good fit for an\nAndroid app. This page explains why some libraries are better suited for app\noptimization and provides general tips to help you choose.\n\nPrefer codegen over reflection\n------------------------------\n\nGenerally, you should choose libraries that use\n[code generation (*codegen*)](https://en.wikipedia.org/wiki/Code_generation_(compiler))\ninstead of reflection. With codegen, the optimizer can more easily determine\nwhat code is actually used at runtime and what code can be removed. It can be\ndifficult to tell whether a library uses codegen or reflection, but there are\nsome signs---see the [tips](#tips) for help.\n\nFor more information about codegen versus reflection, see\n[Optimization for library authors](/topic/performance/app-optimization/library-optimization#use-codegen).\n\nGeneral tips when choosing libraries\n------------------------------------\n\nUse these tips to help ensure that your libraries are compatible with app\noptimization.\n\n### Check for optimization issues\n\nWhen considering a new library, look through the library's issue tracker and\nonline discussions to check if there are issues related to minification or\nconfiguring app optimization. If there are, you should try to look for\nalternatives to that library. Keep in mind the following:\n\n- The [AndroidX libraries](/jetpack/androidx) and libraries such as [Hilt](/training/dependency-injection/hilt-android) work well with app optimization because they use codegen instead of reflection. When they do use reflection, they provide minimal keep rules to keep only the code that is needed.\n- Serialization libraries frequently use reflection to avoid boilerplate code when instantiating or serializing objects. Instead of reflection-based approaches (such as Gson for JSON), look for libraries that use codegen to avoid these problems, for example by using [Kotlin Serialization](https://github.com/Kotlin/kotlinx.serialization) instead.\n- Libraries that include package-wide keep rules should be avoided if possible. Package-wide keep rules can help resolve errors, but broad keep rules should eventually be refined to keep only the code that is needed. For more information, see [Adopt optimizations incrementally](/topic/performance/app-optimization/adopt-optimizations-incrementally).\n\n### Enable optimization after adding a new library\n\nWhen you add a new library, enable optimization afterwards and check if there\nare errors. If there are errors, look for alternatives to that library or write\nkeep rules. If a library isn't compatible with optimization, file a bug with\nthat library.\n\n### Rules are additive\n\nBe aware that keep rules are additive. This means that certain rules that a\nlibrary dependency includes cannot be removed and might impact the compilation\nof other parts of your app. For example, if a library includes a rule to disable\ncode optimizations, that rule disables optimizations for your entire project.\n\n### Check for use of reflection (advanced)\n\nYou might be able to tell if a library uses reflection from inspecting its code.\nIf the library uses reflection, check that it provides associated keep rules. A\nlibrary is probably using reflection if it does the following:\n\n- Uses classes or methods from the `kotlin.reflect` or `java.lang.reflect` packages\n- Uses the functions `Class.forName` or `classLoader.getClass`\n- Reads annotations at runtime, for example if it stores an annotation value using `val value = myClass.getAnnotation()` or `val value =\n myMethod.getAnnotation()` and then does something with `value`\n- Calls methods using the method name as a string, for example:\n\n // Calls the private `processData` API with reflection\n myObject.javaClass.getMethod(\"processData\", DataType::class.java)\n ?.invoke(myObject, data)\n\n### Filter out bad keep rules (advanced)\n\nYou should avoid libraries with keep rules that retain code that should really\nbe removed. But if you must use them, you can filter the rules out as shown in\nthe following code: \n\n // If you're using AGP 8.4 and higher\n buildTypes {\n release {\n optimization.keepRules {\n it.ignoreFrom(\"com.somelibrary:somelibrary\")\n }\n }\n }\n\n // If you're using AGP 7.3-8.3\n buildTypes {\n release {\n optimization.keepRules {\n it.ignoreExternalDependencies(\"com.somelibrary:somelibrary\")\n }\n }\n }\n\nCase study: Why Gson breaks with optimizations\n----------------------------------------------\n\nGson is a serialization library that often causes issues with app optimization\nbecause it heavily uses reflection. The following code snippet shows how Gson is\ntypically used, which can easily cause crashes at runtime. Notice that when you\nuse Gson to get a list of User objects, you don't call the constructor or pass a\nfactory to the `fromJson()` function. Constructing or consuming app-defined\nclasses without either of the following is a sign that a library might be using\nopen-ended reflection:\n\n- App class implementing a library, or standard interface or class\n- Code generation plugin like [KSP](https://github.com/google/ksp)\n\n class User(val name: String)\n class UserList(val users: List\u003cUser\u003e)\n\n // This code runs in debug mode, but crashes when optimizations are enabled\n Gson().fromJson(\"\"\"[{\"name\":\"myname\"}]\"\"\", User::class.java).toString()\n\nWhen R8 analyzes this code and doesn't see the `UserList` or `User` instantiated\nanywhere, it can rename fields, or remove constructors which don't seem to be\nused, causing your app to crash. If you are using any other libraries in similar\nways, you should check that they won't interfere with app optimization, and if\nthey do, avoid them.\n\nNote that [Room](/training/data-storage/room) and\n[Hilt](/training/dependency-injection/hilt-android) both construct app defined\ntypes, but use codegen to avoid the need for reflection."]]