本頁面將說明前景服務失敗的一些常見原因,並協助您找出問題所在。
本文將探討下列問題:
疑難排解前的準備
查看前景服務近期異動
如果前景服務使用不當,可能會對裝置效能和電池續航力造成負面影響。因此,Android 平台版本通常會變更前景服務行為,限制這些不良影響。
如果前景服務發生問題,請參閱前景服務異動說明文件,看看最近是否有任何異動可能導致問題。在下列情況下,請務必檢查是否有變更:
- 先前可正常運作的前景服務程式碼現在無法運作
- 您剛開始在新平台版本上測試,或變更了應用程式指定的 API 級別
此外,如果您是在平台的開發人員預覽版上測試裝置,請務必查看最新版本的開發人員預覽版說明文件。
應用程式無回應 (ANR) 錯誤
在某些情況下,應用程式應關閉前景服務。如果應用程式未停止服務,系統會停止服務並觸發應用程式無回應 (ANR) 錯誤。
短程服務執行時間過長,導致 ANR
使用短服務類型的前景服務必須在短時間內完成,大約三分鐘。時間用盡時,系統會呼叫服務的 Service.onTimeout(int,int) 方法。服務有幾秒鐘的時間可以呼叫 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) 方法。服務有幾秒鐘的時間可以呼叫 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() 啟動服務時,該服務有幾秒的時間可呼叫 ServiceCompat.startForeground(),將自身升級為前景服務。如果服務未執行這項操作,則會擲回內部 ForegroundServiceDidNotStartInTimeException。
診斷:
您可以查看堆疊追蹤,瞭解例外狀況為何,並查看 Logcat,取得更詳細的錯誤資訊。在這種情況下,Logcat 會顯示下列錯誤訊息:
android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException:
Context.startForegroundService() did not then call Service.startForeground()
修正方法:
請確保所有新建立的前景服務都會在幾秒內呼叫 ServiceCompat.startForeground()。
WorkManager:
如果 WorkManager worker 執行前景服務 (呼叫 setForegound 或 setForegroundAsync),您也可能會看到這個例外狀況。當兩個前景 worker 的生命週期重疊,其中一個 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。
- 如果您要求必要權限,但在確認已取得必要權限前就啟動前景服務,可能會收到
修正方法:
啟動前景服務前,請要求所有適當的前景服務權限,並確認您已符合所有其他執行階段必要條件。