本身的app的service老是容易被系統回收,蒐羅了一下,基本上的解決思路有如下幾種: android
1.把service寫成系統服務,將不會被回收(未實踐): app
在Manifest.xml文件中設置persistent屬性爲true,則可以使該服務免受out-of-memory killer的影響。可是這種作法必定要謹慎,系統服務太多將嚴重影響系統的總體運行效率。 this
2.提升service的優先級(未實踐): spa
設置android:priority="1000" xml
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。 ci
注:前臺服務會在狀態欄顯示一個通知,最典型的應用就是音樂播放器,只要在播放狀態下,就算休眠也不會被殺,若是不想顯示通知,只要把參數裏的int設爲0便可。 get
Java代碼 it
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。