Android Service被系统回收的解决方法
自己的app的service總是容易被系統回收,搜羅了一下,基本上的解決思路有以下幾種:
1.把service寫成系統服務,將不會被回收(未實踐):
在Manifest.xml文件中設置persistent屬性為true,則可使該服務免受out-of-memory killer的影響。但是這種做法一定要謹慎,系統服務太多將嚴重影響系統的整體運行效率。
2.提高service的優先級(未實踐):
設置android:priority="1000"
Xml代碼
| 1 2 3 4 5 | <!-- 為了消去加上android:priority="1000"后出現的警告信息,可以設置android:exported屬性,指示該服務是否能夠被其他應用程序組件調用或跟它交互 --> <serviceandroid:name="com.example.helloandroid.weatherforecast.service.UpdateWidgetService"android:exported="false"?> <!-- 為防止Service被系統回收,可以通過提高優先級解決,1000是最高優先級,數字越小,優先級越低 --> <intent-filter?android:priority="1000"></intent-filter> </service> |
3.將服務寫成前臺服務foreground service(已實踐,很大程度上能解決問題,但不能保證一定不會被殺):
重寫onStartCommand方法,使用StartForeground(int,Notification)方法來啟動service。
注:前臺服務會在狀態欄顯示一個通知,最典型的應用就是音樂播放器,只要在播放狀態下,就算休眠也不會被殺,如果不想顯示通知,只要把參數里的int設為0即可。
Java代碼
| 1 2 3 4 5 6 7 8 9 10 | Notification notification =?new?Notification(R.drawable.logo, "wf update service is running", System.currentTimeMillis()); pintent=PendingIntent.getService(this,?0, intent,?0); notification.setLatestEventInfo(this,?"WF Update Service", "wf update service is running!", pintent); //讓該service前臺運行,避免手機休眠時系統自動殺掉該服務 //如果 id 為 0 ,那么狀態欄的 notification 將不會顯示。 startForeground(startId, notification); |
同時,對于通過startForeground啟動的service,onDestory方法中需要通過stopForeground(true)來取消前臺運行狀態。
ps:如果service被殺后下次重啟出錯,可能是此時重發的Intent為null的緣故,可以通過修改onStartCommand方法的返回值來解決:
START_STICKY:如果service進程被kill掉,保留service的狀態為開始狀態,但不保留遞送的intent對象。隨后系統會嘗試重新創建service,由于服務狀態為開始狀態,所以創建服務后一定會調用onStartCommand(Intent,int,int)方法。如果在此期間沒有任何啟動命令被傳遞到service,那么參數Intent將為null。
START_NOT_STICKY:“非粘性的”。使用這個返回值時,如果在執行完onStartCommand后,服務被異常kill掉,系統不會自動重啟該服務。
START_REDELIVER_INTENT:重傳Intent。使用這個返回值時,如果在執行完onStartCommand后,服務被異常kill掉,系統會自動重啟該服務,并將Intent的值傳入。
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保證服務被kill后一定能重啟。
Java代碼
| 1 2 3 4 5 6 7 8 9 10 | Notification notification =?new?Notification(R.drawable.logo, "wf update service is running", System.currentTimeMillis()); pintent=PendingIntent.getService(this,?0, intent,?0); notification.setLatestEventInfo(this,?"WF Update Service", "wf update service is running!", pintent); //讓該service前臺運行,避免手機休眠時系統自動殺掉該服務 //如果 id 為 0 ,那么狀態欄的 notification 將不會顯示。 startForeground(startId, notification); |
4.利用ANDROID的系統廣播檢查Service的運行狀態,如果被殺掉,就再起來(未實踐):
利用的系統廣播是Intent.ACTION_TIME_TICK,這個廣播每分鐘發送一次,我們可以每分鐘檢查一次Service的運行狀態,如果已經被結束了,就重新啟動Service。
轉載于:https://my.oschina.net/tingzi/blog/169716
總結
以上是生活随笔為你收集整理的Android Service被系统回收的解决方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java设计模式(二) 观察者模式
- 下一篇: WPF程序模彷Windows7的桌面任务