Service中onStartCommand方法返回值的探索
前言
onStartCommand方法的返回值 有4種:START_STICKY、START_NOT_STICKY、START_REDELIVER_INTENT、START_STICKY_COMPATIBILITY。
下面通過結合demo測試結果來解釋每種返回值所代表的意義。
先看測試程式碼
伺服器類
MyService.java
package com.noyet.practice.servicedemo.service;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
/**
* package: com.noyet.practice.servicedemo.service
* Created by noyet on 2015/11/19.
*/
public class MyService extends Service {
private final String TAG = "MyService";
private final int DELAY = 2000;
private Handler mHander = new Handler();
private Runnable mTask = new Runnable() {
@Override
public void run() {
Log.d(TAG, DELAY / 1000 + "s after");
// 故意製造異常,使該程序掛掉
Integer.parseInt("ok");
}
};
public static void startService(Context context) {
Intent intent = new Intent(context, MyService.class);
context.startService(intent);
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, " onCreate");
mHander.postDelayed(mTask, DELAY);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, " onStartCommand startId = " + startId);
Log.d(TAG, " onStartCommand intent = " + intent);
/** START_NOT_STICKY | START_STICKY | START_REDELIVER_INTENT | START_STICKY_COMPATIBILITY */
return START_STICKY_COMPATIBILITY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
Log.d(TAG, " onDestroy");
super.onDestroy();
}
}
測試類
MainActivity.java
package com.noyet.practice.servicedemo;
import android.app.Activity;
import android.os.Bundle;
import com.noyet.practice.servicedemo.service.MyService;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyService.startService(this);
}
}
使用START_STICKY作為返回值
測試結果:
程式被異常kill後(服務被重啟了,但intent物件被清除了)
系統在呼叫完onStartCommand()方法後,如果當前服務被終止了,系統會使該服務保持在啟動狀態,不過它不會保留之前傳遞的Intent物件。但是由於它保持啟動狀態,隨後系統會嘗試重新建立service,但之前的Intent物件沒有被儲存。在這個情況下,如果期間沒有任何啟動命令被傳遞到Service,那麼引數Intent將為null。因此使用START_STICKY作為返回值,適用於不執行命令的媒體播放器(或類似的服務),它只是無限期的執行著並等待工作的到來.
使用START_NOT_STICKY作為返回值
測試結果:
程式被異常kill後(服務沒有被重建)
系統在呼叫完onStartCommand方法後,如果當前服務被終止了並且在此期間沒有任何啟動命令被傳遞到Service,那麼系統將是使當前服務退出啟動狀態,並且除非重新呼叫Context.startService(Intent),否則不會重新被建立(即不會重新呼叫onCreate方法)。因為當前服務退出了啟動狀態,所以除非在此期間啟動命令被傳遞到Service,否則也不會呼叫。這是最安全的選項,用來避免在不需要的時候執行你的服務。onStartCommand方法。
使用START_REDELIVER_INTENT作為返回值
測試結果:
程式被異常kill後(服務被重啟了,並保留了intent物件)
使用這個返回值時,如果在執行完onStartCommand後,服務被異常kill掉,系統會自動重啟該服務,並將Intent的值傳入。並且在在該服務呼叫stopSelf方法之前,能夠一直保留intent物件資料。這適用於那些應該立即恢復正在執行的工作的服務,如下載檔案。
使用START_STICKY_COMPATIBILITY作為返回值
START_STICKY的相容版本,但不保證服務被終止後一定能重啟。
測試結果:
程式被異常kill後(服務雖然被重建,但沒有重啟)