1. 程式人生 > >Service中onStartCommand方法返回值的探索

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後(服務雖然被重建,但沒有重啟)
這裡寫圖片描述