Service#onStartCommand返回值解析

rowandjj發表於2015-12-29

Service#onStartCommand返回值解析

Service類有個生命週期方法叫onStartCommand,每次啟動服務(startService)都會回撥此方法。此方法的原型如下:

public int onStartCommand(Intent intent, int flags, int startId)

需要關注的是這個方法有一個整型的返回值,它有以下選項:

START_STICKY_COMPATIBILITY
START_STICKY
START_NOT_STICKY
START_REDELIVER_INTENT

那麼這幾種返回值有什麼作用呢?

通過閱讀文件,我發現它們將影響服務異常終止情況下重啟服務時的行為,預設情況下,當我們的服務因為系統記憶體吃緊或者其他原因被異常終止時,系統會嘗試在某個時刻重新啟動服務,這時,如果Service#onStartCommand方法返回

  1. START_NOT_STICKY:
    服務不會重新建立,除非你再次呼叫startService
  2. START_STICKY/START_STICKY_COMPATIBILITY:
    服務重新建立並啟動,依次回撥onCreate,onStartCommand,但是如果沒有新的intent傳給此service,onStartCommand接受的將是一個空的intent
    START_STICKY_COMPATIBILITY是START_STICKY的相容版本,2.0之下使用,它不保證一定呼叫onStartCommand.

  3. START_REDELIVER_INTENT:
    服務重新建立並啟動,依次回撥onCreate,onStartCommand,並且會把最後一次傳給此服務的intent重新發給onStartCommand


系統預設策略

Service的onStartCommand策略:

public int onStartCommand(Intent intent, int flags, int startId) {
      onStart(intent, startId);
      return mStartCompatibility ? START_STICKY_COMPATIBILITY : START_STICKY;
  }

可見,預設的策略是START_STICKY,支援服務意外終止重新建立的。

IntentService的實現策略:
IntentService不應該重新實現onStartCommand,而是去複寫onHandleIntent.

@Override
  public int onStartCommand(Intent intent, int flags, int startId) {
      onStart(intent, startId);
      return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
  }

  public void setIntentRedelivery(boolean enabled) {
         mRedelivery = enabled;
     }

可見,IntentService預設只支援兩種返回值START_REDELIVER_INTENT或者START_NOT_STICKY,並且由setIntentRedelivery方法決定,預設是START_NOT_STICKY,不重新建立。


測試:

測試機:nexus5,android6.0

注:這裡的kill service模擬的是服務意外被殺死的情形,這裡我通過使用nexus的
close background apps功能,即點選menu鍵,滑掉啟動的app。由於這種做法是由系統殺死service,因而不會回撥service的生命週期方法onDestroy

  1. onStartCommand返回Service.START_STICKY

    • kill Service:

    service會重啟,並重新執行onCreateonStartCommand方法,注意重啟後執行onStartCommand時的intent引數將會是null
    01

    • stop Service:

    僅執行onDestroy,不會重啟服務
    02

  2. onStartCommand返回Service.START_NOT_STICKY

    • kill Service:

    service不會重啟
    01

    • stop Service:

    僅執行onDestroy,不會重啟服務
    02

  3. onStartCommand返回Service.START_REDELIVER_INTENT

    • kill Service:

    service會重啟,並重新執行onCreateonStartCommand方法,注意重啟後執行onStartCommand時的intent引數不為null,也就是說會重新傳送之前的intent。
    01

    • stop Service:

    僅執行onDestroy,不會重啟服務
    02

相關文章