Cold Start คือวงจรการเริ่มต้นสมบูรณ์ของแอปพลิเคชัน Android ที่เริ่มต้นจากสถานะศูนย์ เมื่อกระบวนการของแอปพลิเคชันไม่มีอยู่ในหน่วยความจำและ Activity ยังไม่ได้ถูกสร้างขึ้น ระบบสร้างกระบวนการใหม่ โหลดคลาส เริ่มต้น Application สร้าง Activity และดำเนินการวาดครั้งแรก ตามข้อมูลของ Google, 2024 การเริ่มต้นเย็นบนอุปกรณ์ระดับกลางอาจใช้เวลา 1 ถึง 5 วินาที และทุก ๆ 100 มิลลิวินาทีของความล่าช้าจะลดโอกาสการคงผู้ใช้ไว้ 3%
ประเด็นสำคัญ
Cold Start (การเริ่มต้นเย็น) เป็นสถานการณ์ที่แอปพลิเคชัน Android ถูกเริ่มต้นจากสถานะแรกเริ่มที่สุด: ระบบปฏิบัติการสร้างกระบวนการใหม่ (fork จาก Zygote), จัดสรรหน่วยความจำ, โหลดโค้ด DEX ไปยัง ART, เริ่มต้นคลาสและสร้างอินสแตนซ์ Application จากนั้นจึงสร้าง Activity แรก ก่อนเริ่มแอป ไม่มีข้อมูลเกี่ยวกับแอปในหน่วยความจำของอุปกรณ์ ยกเว้นอิมเมจคลาสที่แคชไว้หากใช้ Background Dexopt
การเริ่มต้นเย็นเกิดขึ้นในสามกรณี: เมื่อเริ่มครั้งแรกหลังจากติดตั้งแอป, เมื่อเริ่มหลังจากรีบูตอุปกรณ์ และเมื่อเริ่มหลังจากระบบลบกระบวนการเนื่องจากหน่วยความจำไม่เพียงพอ บนอุปกรณ์ที่มี RAM 2–4 GB ระบบจะลบกระบวนการพื้นหลังค่อนข้างรุนแรง ดังนั้น Cold Start อาจเกิดขึ้นทุกครั้งที่ผู้ใช้กลับมาใช้แอปหลังจากไม่ได้ใช้งานหลายชั่วโมง ใน Android 12+ ระบบสามารถเก็บกระบวนการที่ถูกแช่แข็ง (freeze / cached) แต่ด้วยการประหยัดหน่วยความจำแบบแอคทีฟ (OOM-killer) กระบวนการจะถูกยุติ
ตามข้อมูลของ Google (รายงาน Find My Device, 2023) 65% ของผู้ใช้ปิดแอปหากไม่เปิดภายใน 3 วินาที สำหรับโซเชียลเน็ตเวิร์กและแอปส่งข้อความที่ผู้ใช้กลับมาหลายสิบครั้งต่อวัน Cold Start ส่งผลโดยตรงต่อการคงผู้ใช้ไว้ ใน Google Play Console เมตริก Cold Start เป็นส่วนหนึ่งของส่วน Android Vitals และแสดงเป็นหนึ่งในตัวบ่งชี้ ANR และประสิทธิภาพ แอปที่เกินเกณฑ์ Cold Start “แย่” (มากกว่า 5 วินาทีบน 25% ของอุปกรณ์) จะได้รับคำเตือนในคอนโซลและอาจถูกลดอันดับในผลการค้นหา
Android แบ่งประเภทการเริ่มต้นแอปเป็นสามแบบ แต่ละแบบมีระยะเวลา ผลกระทบต่อ UX และวิธีการปรับแต่งที่แตกต่างกัน การเข้าใจความแตกต่างเป็นสิ่งจำเป็นสำหรับการเลือกกลยุทธ์การทำโปรไฟล์ที่ถูกต้อง
| ประเภทการเริ่ม | สถานะกระบวนการ | Application.onCreate | เวลาโดยทั่วไป |
|---|---|---|---|
| Cold | ไม่มีกระบวนการ | ดำเนินการ | 1–5 วินาที |
| Warm | มีกระบวนการ, ไม่มี Activity | ไม่ดำเนินการ | 200–600 มิลลิวินาที |
| Hot | กระบวนการ + Activity ในหน่วยความจำ | ไม่ดำเนินการ | < 200 มิลลิวินาที |
Warm Start เกิดขึ้นเมื่อกระบวนการของแอปมีอยู่แล้วในพื้นหลัง แต่ Activity ถูกทำลายไปแล้ว (เช่น ผู้ใช้กลับมาหลังจากหยุดยาวและระบบได้ปล่อยหน่วยความจำ Activity) Hot Start — เมื่อผู้ใช้ย่อแอปและเปิดใหม่อีกครั้งทันที: Activity ถูกหยุดชั่วคราวและการกู้คืนใช้เวลาน้อยที่สุด สำหรับผู้ใช้ Cold Start เป็นประเภทการเริ่มที่สังเกตได้ชัดเจนที่สุด และการปรับแต่งให้ผลการปรับปรุง UX ที่ดีที่สุด
Cold Start สามารถกลายเป็น Warm Start ได้หลังจากที่แอปเริ่มอย่างน้อยหนึ่งครั้ง — ART แคชอิมเมจคลาสที่คอมไพล์แล้ว (Image ใน Boot Profile) และการโหลด DEX ครั้งต่อไปเร็วขึ้น ดังนั้น การเริ่มครั้งที่สองหลังจาก Cold Start ครั้งแรกโดยปกติจะเร็วขึ้น 20–40% หากแอปใช้ Baseline Profiles โปรไฟล์จะถูกโหลดในการเริ่มครั้งแรกและการเริ่มครั้งที่สองอาจเร็วขึ้นอีก: Google Play ที่เผยแพร่ Baseline Profiles ทำให้ Cold Start เร็วขึ้น 30% บนอุปกรณ์ที่ใช้ Android 12+
Cold Start ประกอบด้วยขั้นตอนที่กำหนดไว้อย่างชัดเจน ซึ่งแต่ละขั้นตอนสามารถวัดและปรับแต่งได้อย่างอิสระ การรู้ขั้นตอนช่วยระบุว่าแอปสูญเสียเวลาในขั้นตอนใด Google ระบุสี่ขั้นตอนหลัก: การสร้างกระบวนการ, การเริ่มต้น Application, การสร้าง Activity และเฟรมแรก
ระบบ Android (ActivityManagerService) สร้างกระบวนการใหม่โดย fork จากกระบวนการ Zygote Zygote เป็นกระบวนการที่โหลดไว้ล่วงหน้าพร้อมคลาส Android ทั่วไป Fork ใช้เวลา 30–80 มิลลิวินาที — เวลานี้อยู่นอกเหนือการควบคุมของแอป หลังจาก fork ActivityThread จะเริ่มทำงาน — อินสแตนซ์ของลูปหลักของแอปพลิเคชัน ในขั้นตอนนี้ การโหลดคลาส ก็เกิดขึ้นผ่าน ClassLoader และ ART เริ่มแปลไบต์โค้ดแรก หากแอปใช้ตัวเริ่มต้นแบบสแตติกจำนวนมาก ขั้นตอนนี้อาจยืดเยื้อ
ทันทีหลังจาก ActivityThread เริ่มทำงาน Application.onCreate ถูกเรียก ที่นี่นักพัฒนามักทำผิดพลาดโดยการเริ่มต้นทุกอย่างพร้อมกัน: Crashlytics, Firebase, ไลบรารีเครือข่าย, ฐานข้อมูล, คอมโพเนนต์ Dagger, คอนเทนเนอร์ DI การเริ่มต้นแต่ละครั้งเป็นเวลาที่ถูกบล็อกบนเธรดหลัก หาก Application.onCreate ใช้เวลา 500 มิลลิวินาที ผู้ใช้จะเห็นหน้าจอสีขาว (หรือสีดำ) เป็นเวลาครึ่งวินาที ระยะเวลาที่เหมาะสมของขั้นตอนนี้คือน้อยกว่า 200 มิลลิวินาทีบนอุปกรณ์ระดับกลาง
หลังจากเริ่มต้น Application อินสแตนซ์ Activity ถูกสร้างขึ้น (MainActivity หรือ Launcher Activity) Activity.onCreate ถูกเรียก ซึ่งเกิด setContentView, การเริ่มต้น fragment, การตั้งค่า ViewModel และการสมัครรับ LiveData/Flow หาก onCreate โหลดข้อมูล (SharedPreferences, SQLite, API) แบบซิงโครนัสบนเธรดหลัก ขั้นตอนจะยืดเยื้อ เป้าหมายคือให้ onCreate อยู่ภายใน 200–400 มิลลิวินาทีบนอุปกรณ์ระดับกลาง
หลังจาก onCreate เสร็จสมบูรณ์ การเรนเดอร์ครั้งแรกเริ่มต้น: วัด, เค้าโครง, วาด ช่วงเวลานี้เรียกว่า TTFD (Time To First Draw) หากแอปใช้หน้าจอเริ่มต้น (ผ่าน SplashScreen API บน Android 12+ หรือผ่านธีม) การเรนเดอร์อาจเกิดขึ้นเร็วกว่า แต่ผู้ใช้ยังคงรอจนกว่า splash จะหายไป TTFD ที่เหมาะสำหรับ Cold Start คือน้อยกว่า 1.5 วินาที
การวัด Cold Start ต้องใช้เครื่องมือพิเศษ เนื่องจากการบันทึกปกติ (Log.d) เริ่มทำงานหลังจากสร้าง Application เท่านั้น และเวลาของ fork และการโหลดคลาสยังไม่สามารถเข้าถึงได้ Google แนะนำสามวิธี: คำสั่ง ADB, Android Vitals และมาโครประสิทธิภาพแบบกำหนดเอง
วิธีที่ง่ายและทำซ้ำได้มากที่สุดคือคำสั่ง adb shell am start -S -W แฟล็ก -S หยุดแอปทันที (โดยบังคับ) ก่อนเริ่ม (รับประกัน Cold Start) คำสั่งแสดงสามเมตริก: ThisTime (เวลาเริ่ม Activity), TotalTime (เวลารวมรวมถึงการเริ่มกระบวนการ) และ WaitTime (เวลารวมถึงความล่าช้าทั้งหมดของ Activity Manager) เพื่อการวัดที่สะอาด ให้วัด 5–7 ครั้งและใช้มัธยฐาน — การวัดเดี่ยวมีความไวต่อสัญญาณรบกวน (การลดความเร็ว CPU, โหลดพื้นหลัง)
# Cold Start แบบบังคับพร้อมการวัด
$ adb shell am start -S -W \
com.example.app/.MainActivity
# ผลลัพธ์คำสั่ง:
# ThisTime: 1842 ms
# TotalTime: 1842 ms
# WaitTime: 1855 ms
Google Play Console รวบรวมเมตริกที่ไม่ระบุตัวตนจากอุปกรณ์ทั้งหมดที่ติดตั้งแอป ในส่วน Android Vitals → Launch time การแจกแจงมัธยฐานของ Cold Start ตามรุ่นอุปกรณ์และเวอร์ชัน Android จะแสดงขึ้น นี่เป็นวิธีเดียวที่จะเห็นเมตริกจริงบนอุปกรณ์ของผู้ใช้ ไม่ใช่แค่อุปกรณ์ทดสอบ หาก Cold Start เกิน 5 วินาทีบน Redmi 9A (RAM 2 GB) และ 1.2 วินาทีบน Pixel 8 ปัญหาอยู่ที่ขนาดหน่วยความจำและจำนวนคลาส Google ยังแสดง ความล่าช้าที่ผู้ใช้รับรู้ได้ ตามเปอร์เซ็นไทล์ที่ 25
Google Jetpack Macrobenchmark (ไลบรารี androidx.benchmark) ช่วยให้เขียนการทดสอบการเริ่มแอปแบบมีเครื่องมือวัด การทดสอบติดตั้งแอป เริ่มจากสถานะเย็นและวัดเวลาจนถึงเฟรมแรก Macrobenchmark จะทำงานอัตโนมัติ 20 ครั้ง ทิ้งค่าผิดปกติและแสดงเปอร์เซ็นไทล์ที่เสถียร สำหรับ CI/CD คุณสามารถเปรียบเทียบ baseline และการเริ่มปัจจุบัน — หากเวลาเพิ่มขึ้นไปป์ไลน์ CI สามารถล้มเหลวได้
การปรับแต่ง Cold Start เป็นงานที่เป็นระบบซึ่งส่งผลกระทบต่อหลายระดับของแอป: โค้ด, ทรัพยากร, การกำหนดค่าบิวด์และสถาปัตยกรรมการเริ่มต้น Google แนะนำให้เริ่มจากส่วนที่มีค่าใช้จ่ายสูงที่สุด — Application.onCreate — และค่อยไปยังรายละเอียดเล็ก ๆ
ย้ายการเริ่มต้นทั้งหมดที่ไม่จำเป็นเมื่อเริ่มต้นออกจาก Application.onCreate ไปยังจุดใช้งานแรก Firebase, Crashlytics, SDK วิเคราะห์, การแจ้งเตือนแบบผลัก, คอมโพเนนต์ DI — ทุกอย่างสามารถเริ่มต้นได้หลังจากเรนเดอร์หน้าจอแรก ใช้ Lazy (by lazy) ใน Kotlin หรือการเริ่มต้น ContentProvider ด้วยการเรียก initialize(context) อย่างชัดเจน ตาม Google (Android Performance, 2023) การเริ่มต้นแบบขี้เกียจลด Cold Start ลง 40–60% สำหรับแอปที่ใช้ 5+ SDK
Baseline Profiles คือการคอมไพล์ AOT ของคลาสและเมธอดที่สำคัญซึ่งใช้เมื่อเริ่มแอป หากไม่มี Baseline Profiles ART จะแปลโค้ด DEX หรือคอมไพล์ผ่าน JIT ซึ่งใช้เวลา ด้วยโปรไฟล์ ART จะคอมไพล์เมธอดที่ระบุเป็นโค้ดเนทีฟ (AOT) ระหว่างการติดตั้งแอป Google ระบุว่า Baseline Profiles ทำให้ Cold Start เร็วขึ้น 15–40% บน Android 9+ และสูงถึง 60% ด้วยการปรับแต่ง ART ของ Android 12+ ในการสร้างโปรไฟล์ ให้ใช้ปลั๊กอิน androidx.benchmark:benchmark-baseline-profile-gradle-plugin
ไลบรารี androidx.startup ช่วยให้สามารถจัดลำดับการเริ่มต้นคอมโพเนนต์และดำเนินการใน ContentProvider เดียว แทนที่จะมี ContentProviders หลายตัวจากไลบรารีต่าง ๆ (แต่ละตัวเพิ่ม 1–2 มิลลิวินาทีในการเริ่มต้นเย็น) App Startup รวมพวกมันเป็นกราฟการพึ่งพาและเริ่มต้นตามความจำเป็นเท่านั้น เมื่อเริ่มต้น เฉพาะคอมโพเนนต์ที่ทำเครื่องหมายด้วย @Initializer ที่จำเป็นสำหรับหน้าจอแรกเท่านั้นที่ถูกดำเนินการ สำหรับส่วนที่เหลือ แฟล็ก needEarlyInit = false ถูกตั้งค่า — พวกมันเริ่มทำงานหลังจากการเรนเดอร์ครั้งแรก
// App Startup Initializer — การเริ่มต้นหลังเริ่ม
class AnalyticsInitializer : Initializer<Unit> {
override fun create(context: Context) {
Analytics.init(context)
}
override fun dependencies() = listOf<Class<out Initializer<*>>>()
}
// ใน AndroidManifest.xml ทำเครื่องหมายเป็นตัวเลือก
// <meta-data android:name="AnalyticsInitializer"
// android:value="false" />
ขนาดไฟล์ DEX ส่งผลโดยตรงต่อเวลาโหลดของ ART ใช้ R8/ProGuard เพื่อทำให้โค้ดสับสนและลบโค้ดที่ตายแล้ว (MinifyEnabled = true) เปิดใช้งาน android:extractNativeLibs="false" ในแมนิเฟสต์เพื่อให้ APK ไม่แตกไฟล์ .so เมื่อติดตั้ง สำหรับโปรเจกต์ที่มีการติดตามอ้างอิงมากกว่า 10 รายการ ให้เพิ่ม startup-priority เฉพาะหน้าจอแรกเท่านั้น แต่ละเมธอดที่เกินมาใน DEX เพิ่ม 0.5–2 มิลลิวินาทีในการโหลด และสำหรับแอปที่มีมากกว่า 50k เมธอด (multidex กับ primary dex) — สูงถึง 300 มิลลิวินาที
Android Vitals ใน Google Play Console (ส่วน Launch time) รวบรวมข้อมูลจากอุปกรณ์ทั้งหมดที่ติดตั้งแอป โดยผู้ใช้ยินยอมให้วินิจฉัยแบบไม่ระบุตัวตน เมตริกแบ่งเป็นสามประเภท: “ดี”, “ปานกลาง”, “แย่” ขึ้นอยู่กับเวลา Cold Start
Google กำหนด Cold Start “แย่” เป็นเวลาที่เกิน 5 วินาทีบนอุปกรณ์ใด ๆ อย่างไรก็ตาม ในทางปฏิบัติ สำหรับอุปกรณ์เรือธง (Snapdragon 8 Gen) เวลาที่ดีคือน้อยกว่า 1.5 วินาที สำหรับระดับกลาง — น้อยกว่า 2.5 วินาที สำหรับระดับเริ่มต้น — น้อยกว่า 4 วินาที Android Vitals แสดงมัธยฐานสำหรับแต่ละ รุ่นอุปกรณ์ ซึ่งช่วยให้เข้าใจว่าอุปกรณ์ใดที่แอปเริ่มช้า หาก Cold Start แย่บนอุปกรณ์ Samsung A-series หรือ Xiaomi Redmi สาเหตุมักเป็นหน่วยความจำแฟลชที่ช้าและ RAM ต่ำ (การเร่งความเร็วผ่าน Baseline Profiles ให้ผลดีที่สุดบนอุปกรณ์ดังกล่าว)
นอกจากการแสดงในคอนโซล เมตริก Cold Start ส่งผลต่อการจัดอันดับคุณภาพแอปใน Google Play Search แอปที่มีเปอร์เซ็นต์การเริ่ม “แย่” สูงจะได้รับป้าย “คำเตือนประสิทธิภาพ” บนหน้าติดตั้ง ซึ่งลดการแปลง ตาม Google (Android Performance Playbook, 2024) แอปที่แก้ไขปัญหา Cold Start เพิ่มการแปลงติดตั้งเฉลี่ย 5% และปรับปรุงการคงผู้ใช้ไว้ (D1) 3–7%
สำหรับการตรวจสอบโดยละเอียดยิ่งขึ้น ให้ใช้ Firebase Performance Monitoring มันติดตาม Cold Start ในระดับเซสชัน แบ่งตามเวอร์ชันแอปและเวอร์ชัน Android แตกต่างจาก Android Vitals ตรงที่ Firebase แสดง แผนภาพร่องรอย ของเวลาที่ใช้ตามขั้นตอน ตัวอย่างเช่น คุณสามารถเห็นว่าในเวอร์ชัน 3.2.0 Application.onCreate ใช้เวลา 800 มิลลิวินาที (เนื่องจากไลบรารีการแจ้งเตือนแบบผลักใหม่) ในขณะที่เวอร์ชัน 3.2.1 — 200 มิลลิวินาที (หลังแก้ไข)
ด้านล่างเป็นสองตัวอย่างที่ใช้งานได้จริงซึ่งเร่ง Cold Start โดยตรง: การย้ายการเริ่มต้น SDK หลังเริ่มต้นและการใช้ SplashScreen API
ข้อผิดพลาดทั่วไปคือการเริ่มต้น SDK ทั้งหมดใน Application.onCreate ด้านล่างแสดงวิธีการย้ายการเริ่มต้นที่ไม่สำคัญไปยัง coroutine ที่เริ่มทำงานหลังจากวาดเฟรมแรก สำคัญ: Firebase, Crashlytics และ SDK รายงานข้อขัดข้องต้องเริ่มต้นเมื่อเริ่มแอป — ไม่สามารถเลื่อนได้เนื่องจากจับข้อขัดข้องระหว่างการเริ่มต้นคอมโพเนนต์อื่น สำหรับส่วนที่เหลือให้ใช้ lifecycleScope ใน Activity แรก
// ❌ ไม่ดี — การเริ่มต้นทั้งหมดใน Application.onCreate
class App : Application() {
override fun onCreate() {
super.onCreate()
Firebase.init(this) // สำคัญ
Analytics.init(this) // สามารถทำทีหลัง
Database.init(this) // สามารถทำทีหลัง
ImageLoader.init(this) // สามารถทำทีหลัง
}
}
// ✅ ดี — Firebase เมื่อเริ่ม, ที่เหลือ after inflate
class App : Application() {
override fun onCreate() {
super.onCreate()
Firebase.init(this)
}
}
// ใน MainActivity หลังจากเฟรมแรก:
lifecycleScope.launchWhenResumed {
initializeNonCriticalSdks()
}
บน Android 12+ ให้ใช้ SplashScreen API อย่างเป็นทางการซึ่งแสดง splash ของระบบ (ไอคอนแอปบนพื้นหลังมืด/สว่าง) ทันทีเมื่อกระบวนการเริ่ม สิ่งนี้ซ่อนเวลาเริ่มต้นจากผู้ใช้ — พวกเขาเห็น splash แทนหน้าจอสีขาว สำหรับอุปกรณ์เก่า ให้ใช้ theme-based splash (Theme.SplashScreen ในสไตล์) สำคัญ: splash ไม่ควรนานเกิน 300 มิลลิวินาที — หากแอปยังไม่พร้อม ให้วาดโครงกระดูก “ถาวร” (shimmer) และแสดงความคืบหน้าการโหลด
// SplashScreen API — Android 12+
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
val splashScreen = installSplashScreen()
splashScreen.setKeepOnScreenCondition {
isReady.value == false
}
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
// Splash ตามธีม (Android 5-11)
// ใน themes.xml:
// <style name="Theme.App.Starting" parent="Theme.SplashScreen">
// <item name="windowSplashScreenBackground">@color/white</item>
// <item name="windowSplashScreenAnimatedIcon">@mipmap/ic_launcher</item>
// </style>
คำถามที่พบบ่อย
อีมูเลเตอร์ใช้คอมพิวเตอร์โฮสต์ที่ทรงพลังและจำลองโปรเซสเซอร์ด้วยการเร่งด้วยฮาร์ดแวร์ (HAXM / WHPX) อุปกรณ์จริง โดยเฉพาะรุ่นประหยัด (หน่วยความจำ eMMC แทน UFS) มี I/O ที่ช้ากว่ามาก แนะนำให้วัด Cold Start บนอุปกรณ์จริงระดับกลางเพื่อให้ได้ข้อมูลที่สมจริง
ตามคำแนะนำของ Google ค่ามัธยฐาน Cold Start ควรน้อยกว่า 2 วินาที บนอุปกรณ์ระดับกลาง สำหรับเรือธง — น้อยกว่า 1.5 วินาที สำหรับอุปกรณ์ประหยัด (RAM 2 GB) ยอมรับได้ถึง 4 วินาที แต่แนะนำให้ปรับแต่งให้เหลือ 3 วินาที ค่าที่มากกว่า 5 วินาทีถือว่าวิกฤต
ทางอ้อม — ใช่ หากแมนิเฟสต์มีไอคอนแบบเวกเตอร์ (AdaptiveIcon) จะต้องถูกคอมไพล์เป็น drawable เมื่อเริ่มต้น หากไอคอนมีเส้นทางที่ซับซ้อน (pathData ที่มีเส้นโค้งหลายสิบเส้น) การคอมไพล์ใช้เวลา 10–30 มิลลิวินาที ใช้ VectorDrawable ที่มี pathData ที่ปรับแต่งแล้ว (ผ่าน SVGOMG หรือ Android Studio Vector Asset)
ใช่ หาก Feature Module (Android App Bundle) โหลดตามความต้องการ Cold Start ของมันจะวัดจากเวลาที่แตะฟีเจอร์จนถึงเฟรมแรก โมดูลตามความต้องการโหลดผ่าน Play Core Library และการติดตั้งเพิ่ม 500–3000 มิลลิวินาทีให้กับเวลาเริ่มต้น ปรับแต่งโค้ดฟีเจอร์เช่นเดียวกับโมดูลหลัก
แอปที่มีมากกว่า 64k เมธอดต้องการ Multidex ซึ่งหมายความว่า ART ต้องโหลดไฟล์ DEX หลายไฟล์ เพิ่มเวลา Cold Start 200–800 มิลลิวินาทีขึ้นอยู่กับจำนวนไฟล์ classes.dex ใช้ minSdk 21+ (ART ที่รองรับ multidex ดั้งเดิม) และกำหนดค่า primary dex ผ่าน --main-dex-list เพื่อเก็บคลาสสำคัญไว้ในไฟล์ DEX แรก
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม