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