本頁面會說明前台服務可能失敗的常見原因,並協助您找出問題所在。
本文將探討下列問題:
疑難排解前的準備
檢查前景服務的近期變更
如果使用方式不當,前景服務可能會對裝置效能和電池續航力造成負面影響。因此,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()
。
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
。
- 如果您要求必要權限,但未先確認已授予必要權限就啟動前景服務,可能會收到
修正方法:
啟動前景服務前,請先要求所有適當的前景服務權限,並確認您已符合所有其他執行階段必要條件。