หน้านี้จะอธิบายสาเหตุที่พบบ่อยบางประการที่ทำให้บริการที่ทำงานอยู่เบื้องหน้าล้มเหลว และช่วยคุณระบุสาเหตุของปัญหา
เอกสารนี้จะกล่าวถึงปัญหาต่อไปนี้
ก่อนแก้ปัญหา
ตรวจสอบการเปลี่ยนแปลงล่าสุดของบริการที่ทำงานอยู่เบื้องหน้า
หากใช้บริการที่ทำงานอยู่เบื้องหน้าอย่างไม่เหมาะสม บริการดังกล่าวอาจส่งผลเสียต่อประสิทธิภาพของอุปกรณ์และอายุการใช้งานแบตเตอรี่ ด้วยเหตุนี้ แพลตฟอร์ม Android จึงมักจะทำการเปลี่ยนแปลงลักษณะการทำงานของบริการที่ทำงานอยู่เบื้องหน้าในการเผยแพร่แพลตฟอร์ม Android แต่ละครั้งเพื่อจำกัดผลเสียเหล่านี้
หากพบปัญหาเกี่ยวกับบริการที่ทำงานอยู่เบื้องหน้า คุณควรตรวจสอบการเปลี่ยนแปลง ในเอกสารประกอบของบริการที่ทำงานอยู่เบื้องหน้า และดูว่ามีการเปลี่ยนแปลงล่าสุดที่อาจอธิบาย ปัญหาของคุณได้หรือไม่ คุณควรตรวจสอบการเปลี่ยนแปลงในสถานการณ์ต่อไปนี้เป็นพิเศษ
- โค้ดบริการที่ทำงานอยู่เบื้องหน้าที่เคยทำงานได้ดี ตอนนี้กลับล้มเหลว
- คุณเพิ่งเริ่มทดสอบในการเผยแพร่แพลตฟอร์ม Android ใหม่ หรือคุณได้เปลี่ยนระดับ API ที่แอปกำหนดเป้าหมาย
นอกจากนี้ หากคุณกำลังทดสอบอุปกรณ์ในเวอร์ชันทดลองใช้สำหรับนักพัฒนาแอปของ แพลตฟอร์ม โปรดตรวจสอบเอกสารประกอบเวอร์ชันทดลองใช้สำหรับนักพัฒนาแอป เวอร์ชันล่าสุด
ข้อผิดพลาด "แอปพลิเคชันไม่ตอบสนอง (ANR)"
ในบางกรณี ระบบคาดหวังให้แอปปิดบริการที่ทำงานอยู่เบื้องหน้า หากแอปไม่หยุดบริการ ระบบจะหยุดบริการและทริกเกอร์ข้อผิดพลาด แอปพลิเคชันไม่ตอบสนอง (ANR)
บริการที่ทำงานอยู่เบื้องหน้าประเภท "สั้น" ใช้เวลานานเกินไปจนทำให้เกิด ANR
บริการที่ทำงานอยู่เบื้องหน้าที่ใช้บริการประเภท สั้น
ต้องทำงานให้เสร็จอย่างรวดเร็วภายในเวลาประมาณ 3 นาที เมื่อหมดเวลา ระบบจะเรียกใช้เมธอด ของบริการService.onTimeout(int,int) บริการจะมีเวลา
2-3 วินาทีในการเรียกใช้ stopSelf() หากบริการไม่หยุดตัวเอง ระบบจะทริกเกอร์ข้อผิดพลาด "แอปพลิเคชันไม่ตอบสนอง"
การวินิจฉัย:
หาก ANR เกิดจากบริการที่ทำงานอยู่เบื้องหน้าหยุดตัวเองไม่ได้ ระบบจะแสดงข้อยกเว้นภายใน คุณสามารถยืนยันว่านี่คือปัญหาโดยการตรวจสอบรายงาน ANR หากเป็นปัญหาดังกล่าว รายงานจะมีข้อความต่อไปนี้
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type FOREGROUND_SERVICE_TYPE_SHORT_SERVICE did not stop within its timeout:
[component name]"
การแก้ไข:
ตรวจสอบว่าบริการที่ทำงานอยู่เบื้องหน้าซึ่งมีขีดจำกัดด้านเวลาทั้งหมดทำงานเสร็จและเรียกใช้
stopForeground(int) ภายในขีดจำกัดด้านเวลาของระบบ
กำหนดให้บริการที่ทำงานอยู่เบื้องหน้าใช้ Service.onTimeout(int,int)
ตรวจสอบว่าการใช้งานเมธอดดังกล่าวเรียกใช้ stopSelf() ทันที
ข้อยกเว้นของบริการที่ทำงานอยู่เบื้องหน้า
ส่วนนี้จะอธิบายปัญหาเกี่ยวกับบริการที่ทำงานอยู่เบื้องหน้าหลายประการที่อาจทำให้ระบบแสดงข้อยกเว้น หากแอปไม่ดักจับข้อยกเว้น ผู้ใช้จะเห็นกล่องโต้ตอบแจ้งว่าแอปหยุดทำงานแล้ว
ในบางกรณี ระบบจะแสดงข้อยกเว้นภายใน ในกรณีดังกล่าว คุณสามารถ ดูว่าข้อยกเว้นคืออะไรได้โดยดูในสแต็กเทรซ และ ตรวจสอบLogcat เพื่อดูข้อมูลข้อผิดพลาดโดยละเอียดเพิ่มเติม
ข้อยกเว้นภายใน: หมดเวลา
ระบบกำหนดขีดจำกัดด้านเวลาที่บริการที่ทำงานอยู่เบื้องหน้าประเภท "การซิงค์ข้อมูล" และ "การประมวลผลสื่อ"
สามารถทำงานได้ขณะที่แอปทำงานอยู่ในเบื้องหลัง หากบริการใช้เวลาเกินขีดจำกัด ระบบจะเรียกใช้เมธอด Service.onTimeout(int,int) ของบริการ บริการจะมีเวลา 2-3 วินาทีในการเรียกใช้ stopSelf() หากบริการไม่หยุดตัวเอง ระบบจะสร้าง RemoteServiceException ภายในซึ่งทำให้แอปขัดข้อง
การวินิจฉัย:
คุณสามารถดูว่าข้อยกเว้นคืออะไรได้โดย ดูในสแต็กเทรซ และตรวจสอบ Logcat เพื่อดูข้อมูลข้อผิดพลาดโดยละเอียดเพิ่มเติม ในกรณีนี้ Logcat จะมีข้อความแสดงข้อผิดพลาดต่อไปนี้
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type [service type] did not stop within its timeout: [component name]"
การแก้ไข:
ตรวจสอบว่าบริการที่ทำงานอยู่เบื้องหน้าซึ่งมีขีดจำกัดด้านเวลาทั้งหมดทำงานเสร็จและเรียกใช้ stopForeground(int) ภายในขีดจำกัดด้านเวลาของระบบ
กำหนดให้บริการที่ทำงานอยู่เบื้องหน้าใช้ Service.onTimeout(int,int)
ตรวจสอบว่าการใช้งานเมธอดดังกล่าวเรียกใช้ stopSelf() ทันที
ข้อยกเว้นภายใน: ForegroundServiceDidNotStartInTimeException
เมื่อคุณเปิดใช้บริการโดยการเรียกใช้
context.startForegroundService()
บริการดังกล่าวจะมีเวลา 2-3 วินาทีในการเลื่อนระดับตัวเองเป็นบริการที่ทำงานอยู่เบื้องหน้าโดย
การเรียกใช้
ServiceCompat.startForeground()
หากบริการไม่ดำเนินการดังกล่าว ระบบจะแสดง ForegroundServiceDidNotStartInTimeException ภายใน
การวินิจฉัย:
คุณสามารถดูว่าข้อยกเว้นคืออะไรได้โดย ดูในสแต็กเทรซ และตรวจสอบ Logcat เพื่อดูข้อมูลข้อผิดพลาดโดยละเอียดเพิ่มเติม ในกรณีนี้ Logcat จะมีข้อความแสดงข้อผิดพลาดต่อไปนี้
android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException:
Context.startForegroundService() did not then call Service.startForeground()
การแก้ไข:
ตรวจสอบว่าบริการที่ทำงานอยู่เบื้องหน้าที่สร้างขึ้นใหม่ทั้งหมดเรียกใช้ ServiceCompat.startForeground() ภายในเวลา 2-3 วินาที
WorkManager:
คุณอาจเห็นข้อยกเว้นนี้กับ Worker ของ WorkManager ที่ เรียกใช้
บริการที่ทำงานอยู่เบื้องหน้า
(เรียกใช้ setForegound หรือ setForegroundAsync) เมื่อวงจรการทำงานของ Worker ที่ทำงานอยู่เบื้องหน้า 2 รายการทับซ้อนกันเนื่องจาก Worker รายการหนึ่งพยายามเริ่มบริการที่ทำงานอยู่เบื้องหน้า
ในขณะที่บริการที่ทำงานอยู่เบื้องหน้าที่ทำงานอยู่ก่อนหน้านี้พยายามปิดตัวลง ข้อขัดข้องนี้
จะมาพร้อมกับบันทึกต่อไปนี้
Re-initializing SystemForegroundService after a request to shut-down
เราได้เปิดตัวการแก้ไขข้อขัดข้องนี้ใน WorkManager เวอร์ชัน 2.10.5
หากแอปพบ ข้อยกเว้นนี้ ให้อัปเดตเป็น WorkManager เวอร์ชันล่าสุดและรายงานปัญหาที่ยังคงอยู่ไปยังเครื่องมือติดตามปัญหาของ WorkManager issue tracker
ForegroundServiceStartNotAllowedException
ข้อผิดพลาด:
ระบบแสดง ForegroundServiceStartNotAllowedException
สาเหตุ:
โดยปกติแล้วสาเหตุเกิดจากแอปเปิดใช้บริการที่ทำงานอยู่เบื้องหน้าจากเบื้องหลังเมื่อไม่มีข้อยกเว้นที่ถูกต้อง
ตั้งแต่ Android 12 (ระดับ API 31) เป็นต้นไป แอปไม่ได้รับอนุญาตให้เริ่มบริการที่ทำงานอยู่เบื้องหน้าขณะที่แอปทำงานอยู่ในเบื้องหลัง ยกเว้นในบางกรณี
หากคุณพยายามเริ่มบริการที่ทำงานอยู่เบื้องหน้าจากเบื้องหลังและไม่เป็นไปตามข้อกำหนดของข้อยกเว้นข้อใดข้อหนึ่ง ระบบจะแสดง ForegroundServiceStartNotAllowedException ระบบจะดำเนินการเช่นนี้ด้วยหากคุณไม่เป็นไปตามข้อกำหนดของการยกเว้น
ตัวอย่างเช่น แอปอาจมีปุ่มที่ผู้ใช้คลิกได้ ซึ่งจะทำให้แอปทำการประมวลผลบางอย่างแล้วเปิดใช้บริการที่ทำงานอยู่เบื้องหน้า ในกรณีนี้ ผู้ใช้อาจคลิกปุ่มแล้วนำแอปไปไว้ในเบื้องหลังทันที จากนั้นแอปจะพยายามเปิดใช้บริการจากเบื้องหลัง หากแอปไม่เป็นไปตามข้อยกเว้นที่ระบุข้อใดข้อหนึ่ง ระบบจะแสดง ForegroundServiceStartNotAllowedException
นอกจากนี้ ข้อยกเว้นบางข้อยังมีขีดจำกัดด้านเวลาที่สั้น ตัวอย่างเช่น มีข้อยกเว้นระยะสั้นหากแอปเปิดใช้บริการที่ทำงานอยู่เบื้องหน้าเพื่อตอบสนองต่อข้อความ FCM ที่มีความสำคัญสูง หากคุณไม่เปิดใช้บริการอย่างรวดเร็วพอ คุณจะได้รับ ForegroundServiceStartNotAllowedException
บางครั้งข้อยกเว้นบางข้อจะเข้มงวดมากขึ้นเมื่อมีการเผยแพร่ Android เวอร์ชันใหม่ หากคุณเปลี่ยนเวอร์ชัน Android ที่แอปกำหนดเป้าหมายไว้ ให้ตรวจสอบการเปลี่ยนแปลงในเอกสารประกอบของบริการที่ทำงานอยู่เบื้องหน้าและยืนยันว่าแอปยังคงเป็นไปตามข้อยกเว้นที่อนุญาตข้อใดข้อหนึ่ง
การแก้ไข:
เปลี่ยนเวิร์กโฟลว์ของแอปเพื่อไม่ให้ต้องเปิดใช้บริการที่ทำงานอยู่เบื้องหน้าขณะที่แอปทำงานอยู่ในเบื้องหลัง หรือยืนยันว่าแอปเป็นไปตามข้อยกเว้นข้อใดข้อหนึ่ง
คุณสามารถใช้ คอมโพเนนต์ที่รับรู้ถึงวงจรการทำงาน เพื่อจัดการ วงจรการทำงานของแอป เพื่อไม่ให้พยายามเปิดใช้บริการที่ทำงานอยู่เบื้องหน้า จากเบื้องหลังโดยไม่ตั้งใจ
SecurityException
ข้อผิดพลาด:
ระบบแสดงSecurityException
สาเหตุ:
แอปพยายามเปิดใช้บริการที่ทำงานอยู่เบื้องหน้าโดยไม่มีสิทธิ์ที่จำเป็น
- หากแอปกำหนดเป้าหมายเป็น Android 9 (ระดับ API 28) ขึ้นไป แอปต้องมีสิทธิ์
FOREGROUND_SERVICEเพื่อเปิดใช้บริการที่ทำงานอยู่เบื้องหน้า - หากแอปกำหนดเป้าหมายเป็น Android 14 (ระดับ API 34) ขึ้นไป แอปต้องมีคุณสมบัติตรงตามข้อกำหนดเบื้องต้นทั้งหมดสำหรับประเภทบริการที่ทำงานอยู่เบื้องหน้า ข้อกำหนดเบื้องต้นเหล่านี้มี
รายละเอียดอยู่ใน เอกสารประกอบประเภทบริการที่ทำงานอยู่เบื้องหน้า โปรดทราบข้อกำหนดต่อไปนี้เป็นพิเศษ
- บริการที่ทำงานอยู่เบื้องหน้าหลายประเภทต้องใช้สิทธิ์รันไทม์ที่เฉพาะเจาะจง ตัวอย่างเช่น บริการที่ทำงานอยู่เบื้องหน้าประเภท "การรับส่งข้อความระยะไกล" ต้องมีสิทธิ์
FOREGROUND_SERVICE_REMOTE_MESSAGING
- บริการที่ทำงานอยู่เบื้องหน้าหลายประเภทต้องใช้สิทธิ์รันไทม์ที่เฉพาะเจาะจง ตัวอย่างเช่น บริการที่ทำงานอยู่เบื้องหน้าประเภท "การรับส่งข้อความระยะไกล" ต้องมีสิทธิ์
- ในหลายกรณี มีข้อจำกัดเพิ่มเติมขณะใช้งานเกี่ยวกับสิทธิ์ที่บริการที่ทำงานอยู่เบื้องหน้าบางประเภทต้องใช้ ระบบจะให้สิทธิ์เหล่านี้แก่แอป
เฉพาะในขณะที่แอปทำงานอยู่ในเบื้องหน้า (ยกเว้นในบางกรณี) ซึ่งหมายความว่าแม้ว่าแอปจะขอและได้รับสิทธิ์เหล่านี้ข้อใดข้อหนึ่งแล้ว แต่หากแอปพยายามเปิดใช้บริการที่ทำงานอยู่เบื้องหน้าขณะที่แอปทำงานอยู่ในเบื้องหลัง ระบบจะแสดง
SecurityExceptionแม้ว่าแอปจะมีข้อยกเว้นในการเริ่มบริการที่ทำงานอยู่เบื้องหน้าจากเบื้องหลังก็ตาม ดูข้อมูลเพิ่มเติมได้ที่ ข้อจำกัดในการเริ่มบริการที่ทำงานอยู่เบื้องหน้าที่ต้องใช้สิทธิ์ขณะใช้งาน สิทธิ์- คุณอาจได้รับ
SecurityExceptionหากขอสิทธิ์ที่จำเป็นแล้ว แต่เริ่มบริการที่ทำงานอยู่เบื้องหน้าก่อนที่จะยืนยันว่าได้รับสิทธิ์ที่จำเป็นแล้ว
- คุณอาจได้รับ
การแก้ไข:
ก่อนเปิดใช้บริการที่ทำงานอยู่เบื้องหน้า ให้ขอสิทธิ์บริการที่ทำงานอยู่เบื้องหน้าที่เหมาะสมทั้งหมด และยืนยันว่าคุณมีคุณสมบัติตรงตามข้อกำหนดเบื้องต้นอื่นๆ ทั้งหมดในรันไทม์