調(diào)用startService會拋出IllegalStateException異常解決
調(diào)用startService會拋出IllegalStateException異常
startService可以很方便的啟動一個service服務(wù),也可以運(yùn)行在單獨(dú)的進(jìn)程。
但是如果在后臺調(diào)用了startService,則很可能會拋出一個崩潰。
Caused by: java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.test.broadservice/.MyService }: app is in background uid UidRecord{b67c471 u0a86 RCVR idle change:uncached procs:1 seq(0,0,0)}
at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1577)
at android.app.ContextImpl.startService(ContextImpl.java:1532)
at android.content.ContextWrapper.startService(ContextWrapper.java:664)
at android.content.ContextWrapper.startService(ContextWrapper.java:664)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1661)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
錯誤原因
Android8.0之后,系統(tǒng)增加了對后臺Service的限制,如果應(yīng)用處于后臺,調(diào)用startService會拋出IllegalStateException。
意思是,在后臺的應(yīng)用,不允許調(diào)用startService啟動一個后臺服務(wù),否則就會拋出異常。
解決方法
1. 使用startForegroundService
使用方法比較簡單,這里就不列出代碼了。
有幾點(diǎn)需要注意:
- 用此方法啟動前臺服務(wù),會在用戶的通知欄上顯示
- 必須在
5s內(nèi)調(diào)用服務(wù)的startForeground方法,否則會發(fā)生ANR
2. 使用JobScheduler
使用JobScheduler可以實現(xiàn)在后臺運(yùn)行任務(wù)。
定義一個JobService:
public class MyJobService extends JobService {
@Override
public boolean onStartJob(JobParameters params) {
return false;
}
@Override
public boolean onStopJob(JobParameters params) {
return false;
}
}onStartJob:
- 運(yùn)行在主進(jìn)程,需要避免執(zhí)行耗時的操作。
- 返回true:表示任務(wù)還在繼續(xù)執(zhí)行
- 返回false:表示任務(wù)已執(zhí)行完
- 執(zhí)行完之后,可以調(diào)jobFinished方法來通知系統(tǒng)任務(wù)已完成。
onStopJob:
- 當(dāng)條件不滿足的時候,會回調(diào)
- 返回true:表示條件滿足時,再次執(zhí)行任務(wù)
- 返回false:表示任務(wù)完全結(jié)束
注冊JobService:
<service
android:name=".MyJobService"
android:permission="android.permission.BIND_JOB_SERVICE" />定義一個JobInfo:
JobInfo.Builder builder = new JobInfo.Builder(111, new ComponentName(this, MyJobService.class)); // todo 設(shè)置任務(wù)的參數(shù)
將任務(wù)發(fā)布給系統(tǒng):
JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); jobScheduler.schedule(builder.build());
3. 使用WorkManager
WorkManager是JobScheduler的升級版本,且支持多進(jìn)程,可以將任務(wù)運(yùn)行到單獨(dú)的進(jìn)程中。具體使用方法可以參考之前的文章:應(yīng)用退出后繼續(xù)運(yùn)行后臺任務(wù),來試試WorkManager吧!
總結(jié)
Android 8.0版本以上,在后臺調(diào)用startService會拋出IllegalStateException異常,需要改用其他的方式來使用。
常用的方法有如下三種:
startForegroundService: 這種方式會在用戶的通知欄顯示UI。JobScheduler:可以實現(xiàn)后臺無感知運(yùn)行任務(wù)。WorkManager:Jetpack里的庫,JobScheduler的升級版,支持多進(jìn)程。
以上就是調(diào)用startService會拋出IllegalStateException異常解決的詳細(xì)內(nèi)容,更多關(guān)于startService IllegalStateException的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android App端與PHP Web端的簡單數(shù)據(jù)交互實現(xiàn)示例
本篇文章主要介紹了Android App端與PHP Web端的簡單數(shù)據(jù)交互實現(xiàn)示例,詳細(xì)的介紹了交互的代碼,非常具有實用價值,有興趣的可以了解一下2017-10-10
Android FTP 多線程斷點(diǎn)續(xù)傳下載\上傳的實例
本篇文章主要介紹了Android FTP 多線程斷點(diǎn)續(xù)傳下載\上傳的實例,具有一定的參考價值,有興趣的可以了解一下2017-08-08
Android開發(fā)筆記之如何正確獲取WebView的網(wǎng)頁Title
獲取h5頁面的攜帶的title中是很簡單的,下面這篇文章主要給大家介紹了關(guān)于Android開發(fā)筆記之如何正確獲取WebView的網(wǎng)頁Title的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面來一起看看吧2018-09-09
Android自定義EditText實現(xiàn)淘寶登錄功能
這篇文章主要為大家詳細(xì)介紹了Android自定義EditText實現(xiàn)淘寶登錄功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-12-12
Android開發(fā)自定義控件之折線圖實現(xiàn)方法詳解
這篇文章主要介紹了Android開發(fā)自定義控件之折線圖實現(xiàn)方法,結(jié)合實例形式詳細(xì)分析了Android自定義控件中折線圖原理、實現(xiàn)方法與操作注意事項,需要的朋友可以參考下2020-05-05
Android Bluetooth藍(lán)牙技術(shù)使用流程詳解
這篇文章主要介紹了Android Bluetooth藍(lán)牙技術(shù)使用流程詳解的相關(guān)資料,需要的朋友可以參考下2016-02-02

