แครชแอป: คืออะไร สาเหตุที่แอปปิด และวิธีการตรวจจับ

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-07-27 เวลาอ่าน: 7 นาที

แครชแอป — การสิ้นสุดที่ผิดปกติซึ่งโปรแกรมหยุดตอบสนองและปิดตัวลง ในการพัฒนามือถือ แครชเป็นแหล่งหลักของรีวิวเชิงลบและการลดลงของคะแนน ตามข้อมูลของ Firebase (2024) ผู้ใช้ลบแอปหลังจากแครชหนึ่งหรือสองครั้งใน 53% ของกรณี แต่ละแครชลดการรักษาผู้ใช้ลง 3–5% ระบบตรวจสอบอย่าง Crashlytics และ Sentry ช่วยค้นหาและแก้ไขสาเหตุของแครชได้อย่างรวดเร็วก่อนที่จะส่งผลกระทบต่อผู้ใช้จำนวนมาก

ประเด็นสำคัญ

  • แครช — การสิ้นสุดแอปโดยไม่คาดคิดเนื่องจากข้อผิดพลาดรันไทม์ที่ไม่ได้รับการจัดการ
  • สาเหตุหลัก — NullPointerException, OutOfMemoryError, IndexOutOfBounds, ANR ใน Android
  • Crashlytics — มาตรฐานการตรวจสอบแครชพร้อมการรวบรวม stack trace อัตโนมัติและการจัดกลุ่ม
  • ข้อยกเว้นรันไทม์ — ข้อยกเว้นที่คอมไพเลอร์ไม่ได้ตรวจสอบ จะปรากฏเฉพาะในรันไทม์เท่านั้น
  • กลยุทธ์การป้องกัน — การกำหนดชนิดข้อมูลที่เข้มงวด การผูกแบบเลือกได้ การจัดการข้อผิดพลาด และการทดสอบ

แครชแอปคืออะไร

แครช — การสิ้นสุดโปรแกรมโดยไม่คาดคิดที่เกิดจากสถานการณ์พิเศษที่โค้ดไม่ได้จัดการ ในระบบปฏิบัติการมือถือ แครชนำไปสู่การปิดแอปทันทีและแสดงหน้าจอ “แอปหยุดทำงาน” หรือกลับไปที่หน้าจอหลัก

แครชแบ่งออกเป็นสองประเภทใหญ่ ข้อผิดพลาดที่จัดการแล้ว — บล็อก try/catch จับข้อยกเว้น แอปยังคงทำงานต่อไป อาจสูญเสียฟังก์ชันบางอย่าง แครชที่ไม่ได้รับการจัดการ — ข้อยกเว้นลอยขึ้นไปจนถึงระดับระบบปฏิบัติการ และระบบฆ่ากระบวนการ ประเภทที่สองอันตรายเป็นพิเศษเพราะผู้ใช้ไม่สามารถบันทึกข้อมูลได้

ระบบที่มีผู้ใช้สองล้านคนและอัตราแครช 0.1% สูญเสีย 2,000 ผู้ใช้ ในทุกรุ่น ตาม Google Play Console (2024) แอปที่มีอัตราแครชสูงกว่า 1.5% จะถูกแยกออกจากคำแนะนำและสูญเสียการเข้าชมทั่วไปสูงถึง 30%

สาเหตุหลักของแครชในแอปมือถือ

NullPointerException (NPE) — ราชาแห่งแครชใน Java/Kotlin การพยายามเรียกเมธอดบนออบเจ็กต์ที่เป็น null ใน Kotlin NPE พบได้น้อยกว่าเนื่องจาก null safety แต่ยังคงเป็นไปได้เมื่อใช้ตัวดำเนินการ !! หรือโต้ตอบกับโค้ด Java Google (2024) ประมาณการว่า NPE คิดเป็น 25% ของแครชแอป Android ทั้งหมด

IndexOutOfBoundsException — การเข้าถึงสมาชิกรายการด้วยดัชนีที่ไม่มีอยู่ สาเหตุทั่วไป: ข้อมูลมาจากเซิร์ฟเวอร์ในรูปแบบที่ไม่คาดคิด และ UI พยายามแสดงตำแหน่งที่ไม่มีอยู่ วิธีแก้ไข — ตรวจสอบขนาดของคอลเล็กชันก่อนเข้าถึงตามดัชนีเสมอ

ANR (Application Not Responding) — ปัญหาเฉพาะของ Android เธรด UI ถูกบล็อกนานกว่า 5 วินาที สาเหตุหลัก: คำขอเครือข่ายบนเธรดหลัก การคำนวณหนัก การซิงโครไนซ์ฐานข้อมูล StrictMode ใน Android ช่วยตรวจจับการบล็อกเธรด UI ในระหว่างการพัฒนา

OutOfMemoryError (OOM) — แอปเกินขีดจำกัดหน่วยความจำ บนอุปกรณ์มือถือที่มี RAM 2–4 GB OOM เป็นปัญหาทั่วไปเมื่อทำงานกับรูปภาพขนาดใหญ่หรือรายการไม่สิ้นสุดโดยไม่มีการแบ่งหน้า วิธีแก้ไข — Glide/Coil สำหรับโหลดรูปภาพ LruCache สำหรับแคช ViewHolder ใน RecyclerView

ข้อยกเว้นรันไทม์และข้อผิดพลาดร้ายแรง

ข้อยกเว้นรันไทม์ — ข้อผิดพลาดที่คอมไพเลอร์ไม่ได้ตรวจสอบในเวลาสร้าง จะปรากฏเฉพาะเมื่อโค้ดทำงานบนอุปกรณ์เฉพาะกับข้อมูลเฉพาะเท่านั้น ใน Java ได้แก่ RuntimeException และคลาสย่อย: NullPointerException, IllegalArgumentException, ArithmeticException

ข้อผิดพลาดร้ายแรง (FATAL) — ไม่ใช่รันไทม์ แต่เป็นความล้มเหลวของระบบ Signal 11 (SIGSEGV) — การละเมิดการแบ่งส่วนหน่วยความจำในโค้ดเนทีฟ Signal 6 (SIGABRT) — การสิ้นสุดที่ผิดปกติซึ่งเกิดจากแอปเองผ่าน abort() แครชประเภทนี้วินิจฉัยได้ยากเนื่องจาก stack trace มักไม่แสดงบริบทที่ชัดเจน

ใน iOS สาเหตุหลักคือ NSInvalidArgumentException (nil ที่ไม่คาดคิดในพารามิเตอร์) และ EXC_BAD_ACCESS (การเข้าถึงหน่วยความจำที่ถูกปลดปล่อย) Swift ลดจำนวนแครชลงเมื่อเทียบกับ Objective-C แต่ข้อผิดพลาดในรันไทม์ของ ObjC และไลบรารี C ยังคงทำให้เกิดแครช

การตรวจสอบและการรวบรวมบันทึกแครช

Firebase Crashlytics — มาตรฐานสำหรับแอปมือถือ รวบรวม stack trace โดยอัตโนมัติ เพิ่มบันทึก ID ผู้ใช้ และเมทาดาตาของอุปกรณ์ จัดกลุ่มแครชตามลายเซ็น (คลาสข้อผิดพลาด + บรรทัด) การแจ้งเตือนแบบเรียลไทม์ — การแจ้งเตือนเมื่ออัตราแครชเกินเกณฑ์ที่กำหนด (เช่น >0.1% ต่อชั่วโมง)

Sentry — ทางเลือกที่มีความสามารถยืดหยุ่นมากขึ้น ช่วยให้สร้างบริบทแบบกำหนดเอง เพิ่ม breadcrumbs (เหตุการณ์ก่อนหน้า) กำหนดค่าการกรองในแอปเพื่อแยกข้อผิดพลาดที่ไม่สำคัญ ซอร์สแมป สำหรับ Kotlin และ Swift ช่วยให้เห็นซอร์สโค้ดแทนชื่อที่ถูกทำให้สับสน

แนวปฏิบัติที่ดีที่สุดสำหรับบันทึก: ส่งเมทาดาทาหลักก่อนดำเนินการที่อันตราย — วิธีนี้บันทึกจะแสดงสิ่งที่ผู้ใช้กำลังทำก่อนแครช เพิ่ม คีย์แบบกำหนดเอง (หมายเลขเวอร์ชัน API, หน้าจอล่าสุด, ขนาดข้อมูลนำเข้า) ซึ่งเปลี่ยน stack trace ที่ไร้ประโยชน์ให้เป็นข้อมูลที่นำไปปฏิบัติได้

ตัวอย่าง: การตั้งค่า Crashlytics ใน Android

kotlin
class PaymentViewModel : ViewModel() {
    fun processPayment(amount: Double) {
        crashlytics.setCustomKey("last_screen", "payment")
        crashlytics.setCustomKey("amount", amount)
        try {
            api.charge(amount)
        } catch (e: Exception) {
            crashlytics.recordException(e)
        }
    }
}

กลยุทธ์การป้องกันแครช

การผูกแบบเลือกได้และ null safety — ใน Kotlin ใช้ `?` สำหรับชนิดที่อนุญาตให้เป็น null, `let` และ `?:` สำหรับการจัดการ null อย่างปลอดภัย ใน Swift — optionals และ guard let Kotlin สมัยใหม่ (2024) เพิ่มคำอธิบายประกอบ Contract: `@ContractsDsl` อนุญาตให้ประกาศว่าฟังก์ชันไม่ส่งคืน null และคอมไพเลอร์ตรวจสอบ

การจัดการข้อผิดพลาดในเครือข่าย — ทุกคำขอเครือข่ายต้องจัดการกับหมดเวลา ข้อผิดพลาดในการแยกวิเคราะห์ และความล้มเหลวของเซิร์ฟเวอร์ Retrofit ด้วยชนิด Result — คลาส sealed ที่รับประกันว่าข้อผิดพลาดจะถูกจัดการ รูปแบบไม่มีข้อยกเว้น: แทนที่จะใช้ try/catch ให้ใช้ Result sealed สำหรับการจัดการความสำเร็จและข้อผิดพลาดอย่างชัดเจน

แฟล็กคุณลักษณะ — ปิดการทำงานที่มีปัญหาในระยะไกลโดยไม่ต้องปล่อยเวอร์ชันใหม่ หากการทำงานฝั่งเซิร์ฟเวอร์ทำให้เกิดแครชบนอุปกรณ์เก่า แฟล็กจะปิดการทำงานสำหรับกลุ่มนั้น Firebase Remote Config ช่วยให้เปลี่ยนพฤติกรรมของแอปโดยไม่ต้องเผยแพร่ในร้านค้า

การเปิดตัวแบบค่อยเป็นค่อยไป — ปล่อยเวอร์ชันใหม่ให้ผู้ใช้ 5% และตรวจสอบอัตราแครช หากอัตรายังคงต่ำกว่าเป้าหมาย (ปกติ <0.1%) ให้ขยายเป็น 25% จากนั้น 50% จากนั้น 100% Google Play Console และ App Store Connect รองรับการเปิดตัวแบบเป็นระยะเพื่อหยุดอัตโนมัติเมื่อเกินเกณฑ์

แผนปฏิบัติการเมื่อตรวจพบข้อผิดพลาด

ขั้นตอนที่ 1: การจำแนกประเภท — กำหนดความรุนแรง: วิกฤต (แครชใน >1% ของผู้ใช้), สูง (0.1–1%), ปานกลาง (<0.1%) สำหรับแครชวิกฤต — ตอบสนองทันที สำหรับส่วนที่เหลือ — กระบวนการแก้ไขข้อบกพร่องมาตรฐานในสปรินต์ปัจจุบัน Google Play Console จําแนกแครชโดยอัตโนมัติตามจำนวนผู้ใช้ที่ได้รับผลกระทบ

ขั้นตอนที่ 2: การวิเคราะห์ stack trace — เปิดบันทึกใน Crashlytics ดูตำแหน่งแครชที่แน่นอน ตรวจสอบคีย์แบบกำหนดเอง: หน้าจอใด ข้อมูลใด เวอร์ชันระบบปฏิบัติการ เชื่อมโยงกับการปรับใช้ล่าสุด — บ่อยครั้งที่แครชเกิดจากการเปลี่ยนแปลงโค้ดล่าสุดที่ส่งผลต่อสถานการณ์การใช้งานที่ไม่คาดคิด

ขั้นตอนที่ 3: การจำลอง — พยายามจำลองแครชบนอุปกรณ์หรืออีมูเลเตอร์ที่มีพารามิเตอร์คล้ายกัน หากไม่สำเร็จ ให้ตรวจสอบบันทึกแครชสำหรับรูปแบบ: รุ่นเฉพาะ (Samsung A10), เวอร์ชัน Android (API < 26), ตำแหน่งที่ตั้ง วิธีแก้ไข — เพิ่มเงื่อนไขป้องกันที่ครอบคลุมสถานการณ์

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

คำถามที่พบบ่อย

อัตราแครชเท่าใดที่ถือว่าปกติ

อัตราแครชปกติ — ต่ำกว่า 0.1% สำหรับรุ่นโปรดักชัน Google Play แนะนำให้รักษาอัตราแครชต่ำกว่า 1.5% แต่แอประดับสูง (YouTube, Instagram) รักษาที่ 0.01–0.05% สำหรับรุ่นที่มีฟังก์ชันใหม่ อนุญาตให้เพิ่มขึ้นชั่วคราวถึง 0.5% โดยจะลดลงหลังจากฮอตฟิกซ์

แครชต่างจาก ANR อย่างไร

แครช — แอปสิ้นสุดอย่างผิดปกติ ANR (Application Not Responding) — แอปค้างนานกว่า 5 วินาทีแต่ไม่ได้ปังับ ผู้ใช้เห็นไดอะล็อก “แอปไม่ตอบสนอง” และสามารถรอหรือปิดได้ ปัญหา ANR ไม่ร้ายแรงน้อยกว่าแครชและยังส่งผลต่อคะแนนในร้านค้าด้วย

ทำไมแครชถึงไม่เกิดขึ้นบนทุกอุปกรณ์

อุปกรณ์ต่างกันมีเวอร์ชันระบบปฏิบัติการ ขนาดหน่วยความจำ เวอร์ชันไลบรารี และแม้แต่โปรเซสเซอร์ต่างกัน ตัวอย่าง: แครชบน Android 6 (API 23) เนื่องจากการขาดสิทธิ์รันไทม์อาจไม่เกิดขึ้นบน Android 12 วิเคราะห์บันทึกแครชตามตัวกรอง: เวอร์ชันระบบปฏิบัติการ รุ่นอุปกรณ์ ปริมาณ RAM ซึ่งจะบ่งบอกถึงลักษณะเฉพาะของปัญหา

วิธีหาสาเหตุของแครชเมื่อ stack trace ไม่ให้ข้อมูล

เพิ่ม breadcrumbs แบบกำหนดเอง ใน Crashlytics: บันทึกเหตุการณ์สำคัญก่อนดำเนินการ หากแครชเกิดขึ้นที่ขั้นตอนที่ 3 ของการแนะนำ แสดงว่ามีปัญหาในหน้าจอเฉพาะ สัญลักษณ์ดีบัก (dSYM, ProGuard mapping) — อัปโหลดไปยัง Crashlytics เสมอเพื่อดูชื่อฟังก์ชันจริงแทนชื่อที่ถูกทำให้สับสน

ควรทำให้แอปแครชสำหรับข้อผิดพลาดที่ไม่ร้ายแรงหรือไม่

ในโปรดักชัน — ไม่เคย แครชที่ไม่ได้รับการจัดการ ทำให้ประสบการณ์ผู้ใช้แย่ลง ใช้ try/catch พร้อมการบันทึกข้อผิดพลาด ในโหมดดีบัก การทำให้แครชเป็นที่ยอมรับได้สำหรับการตอบสนองอย่างรวดเร็วต่อนักพัฒนา การยืนยัน — สำหรับตรวจสอบอินวาเรียนต์ที่ไม่ควรถูกละเมิด แต่เฉพาะในบิลด์ดีบักเท่านั้น

สรุป

  • แครช — การสิ้นสุดแอปอย่างผิดปกติที่นำไปสู่การสูญเสียผู้ใช้และการลดลงของคะแนนในร้านค้า
  • NullPointerException — สาเหตุที่พบบ่อยที่สุดของแครชในแอปมือถือ (25% ของแครชทั้งหมด)
  • ANR และ OOM — ปัญหาร้ายแรงเฉพาะของ Android ที่ต้องมีการตรวจสอบและป้องกันแยกต่างหาก
  • Crashlytics และ Sentry — เครื่องมือหลักสำหรับรวบรวม stack trace พร้อมการจัดกลุ่มและการแจ้งเตือนแบบเรียลไทม์
  • การจัดการข้อผิดพลาด — การผูกแบบเลือกได้ ชนิด Result sealed และการตรวจสอบป้องกันช่วยป้องกันแครชส่วนใหญ่
  • แฟล็กคุณลักษณะและการเปิดตัวแบบค่อยเป็นค่อยไป — ลดผลกระทบของข้อบกพร่องต่อผู้ใช้ ช่วยให้สามารถย้อนกลับโค้ดที่มีปัญหา
  • หลังจากแก้ไขแครช — การทดสอบการถดถอยเป็นสิ่งจำเป็นเพื่อป้องกันการเกิดซ้ำของปัญหา

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม