แก้ปัญหาบริการที่ทำงานอยู่เบื้องหน้า

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

เอกสารนี้จะกล่าวถึงปัญหาต่อไปนี้

ก่อนแก้ปัญหา

ตรวจสอบการเปลี่ยนแปลงล่าสุดของบริการที่ทำงานเบื้องหน้า

หากใช้บริการที่ทำงานอยู่เบื้องหน้าอย่างไม่เหมาะสม บริการดังกล่าวอาจส่งผลเสียต่อ ประสิทธิภาพของอุปกรณ์และระยะเวลาการใช้งานแบตเตอรี่ ด้วยเหตุนี้ แพลตฟอร์ม 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()ภายในไม่กี่วินาที

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 หากขอสิทธิ์ที่จำเป็น แต่เริ่มบริการที่ทำงานอยู่เบื้องหน้าก่อนที่จะยืนยันว่าได้รับสิทธิ์ที่จำเป็น แล้ว

แก้ไข

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