Android Service被系統回收的解決方法

本身的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。

相關文章
相關標籤/搜索