Service onStartCommand返回值問題

通過 startService 啓動的服務,一定會調用 service 的 onStartCommand 方法。


Service 源碼裏面,onStartCommand 方法的原型


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


而我們覆寫該方法是這樣的


        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
                 // todo
                return super.onStartCommand(intent, flags, startId);
        }


該方法有返回值,類型爲 int,而我們返回父類的 onStartCommand 結果,即:

START_STICKY_COMPATIBILITY 或者 START_STICKY。


那麼,到底返回哪個呢?還得看 mStartCompatibility 的值


 mStartCompatibility = 

            getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.ECLAIR;


可以看出,只要我們的應用程序 targetSdkVersion 小於 2.0

那麼就返回 START_STICKY_COMPATIBILITY,否則返回 START_STICKY。


當然我們可以自己返回指定的值,不返回父類的結果。但是究竟可以返回哪些?


查看 api 文檔,關於 onStartCommand 的介紹




繼續跟蹤 START_CONTINUATION_MASK,會發現


START_STICKY

START_NOT_STICKY

START_REDELIVER_INTENT

START_STICKY_COMPATIBILITY


爲了,解釋這幾個 int 值的含義,除了結合 api 文檔(尼嘛,很難懂,有木有!),必須實踐。


原理:PlayerService -- > Runnable -- > run 製造異常,模擬系統殺死該進程。


在實驗之前,爲了確保實驗的準確性請做到 abcde


a. 將你的模擬器或者真機調整到 settings/application/running service 界面


                                                    


b. 在每個實驗之前使用  adb  uninstall mark.zhang 卸載這個應用程序,並確保 success


c. 使用 eclipse 直接 run 該應用程序或者命令行 adb install ×××.apk


d. 第一次出現下面提示框,點擊 Force close,稍等一會,再次看運行結果,打印信息


                                                             


e. 再次出現上面對話框直接關閉,不用再等,服務只會自動重啓一次



------------------------------------------ start ---------------------------




1.  START_STICKY




可以看出,再次調用 onCreate、onStartCommand,並且 startId = 2, 但是 intent = null



2.  START_NOT_STICKY




這次並沒有重啓。



3.  START_STICKY_COMPATIBILITY




只調用了oncreate 方法,沒有調用 onStartCommand 



4.  START_REDELIVER_INTENT




可以看出,再次調用 onCreate、onStartCommand,並且 startId = 1, 但是 intent 不爲 null

說明該 int 可以保留上次的 startId 與 intent



------------------------------------------ end ---------------------------



-------------- 附錄


PlayerActivity.java


package mark.zhang;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class PlayerActivity extends Activity {

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

	}

	public void onService(View view) {
		Intent intent = new Intent(PlayerActivity.this, PlayerService.class);
		startService(intent);
	}

}

PlayerService.java


package mark.zhang;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;

public class PlayerService extends Service {
	private static final String TAG = "PlayerService";

	private static final long DELAY = 2000;

	private Handler sWork = new Handler();

	private Runnable task = new Runnable() {

		@Override
		public void run() {
			Log.d(TAG, DELAY / 1000 + "s after-----------");
			// 故意製造異常,使該進程掛掉
			Integer.parseInt("ok");
		}
	};

	@Override
	public IBinder onBind(Intent intent) {
		Log.d(TAG, "onBind------");
		return null;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		Log.d(TAG, "onCreate------");
		sWork.postDelayed(task, 5000);
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.d(TAG, "onStartCommand------and startId = " + startId);
		Log.d(TAG, "onStartCommand------and intent = " + intent);
		// 實驗中,可輪換這幾個值測試
		return START_NOT_STICKY;// | START_STICKY | START_STICKY_COMPATIBILITY |
							// START_REDELIVER_INTENT;
	}

	@Override
	public void onDestroy() {
		Log.d(TAG, "onDestroy------");
		super.onDestroy();
	}

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章