1. 程式人生 > >Service 生命週期

Service 生命週期

先看一段程式碼在LogCat中新增一個標籤,觀察Service生命週期的過程。

import android.app.Service;

import android.content.Intent;

import android.os.IBinder;

import android.util.Log;

public class ServiceLeft extends Service {

private static final String TAG = "ServiceLeft";

@Override

public IBinder onBind(Intent arg0) {

return null;

}

@Override

public void onCreate() {

// //進行建立

Log.i(TAG, "onCreate");

super.onCreate();

}

@Override

public void onDestroy() {

// 進行銷燬

Log.i(TAG, "onDestroy");

super.onDestroy();

}

@Override

public void onStart(Intent intent, int startId) {

// 進行開始

Log.i(TAG, "onStart");

super.onStart(intent, startId);

}

}

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

public class Main extends Activity implements OnClickListener {

private Button llbstatr;

private Button llbstop;

private

Intent serviceIntent;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

llbstatr = (Button) findViewById(R.id.llbstart);

llbstop = (Button) findViewById(R.id.llbstop);

llbstatr.setOnClickListener(this);// 繫結器

llbstop.setOnClickListener(this);

serviceIntent = new Intent(this, ServiceLeft.class);

// 跳轉ServiceLeft生命週期並且呼叫方法

}

@Override

public void onClick(View v) {

// 根據按鈕,觸發事件

switch (v.getId()) {

case R.id.llbstart:

startService(serviceIntent);

break;

case R.id.llbstop:

stopService(serviceIntent);

break;

}

}

}

一個從service播放音樂的音樂播放器,應被設定為前臺執行,因為使用者會明確地注意它的執行.在狀態列中的通知可能會顯示當前的歌曲並且允許使用者啟動一個activity來與音樂播放器互動。
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),

System.currentTimeMillis());

Intent notificationIntent = new Intent(this, ExampleActivity.class);

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(this, getText(R.string.notification_title),

getText(R.string.notification_message),pendingIntent);

startForeground(ONGOING_NOTIFICATION,notification);

要請求你的service運行於前臺,呼叫startForeground().此方法有兩個引數:一個整數唯一的標識一個通知,和這個用於狀態列的通知,例如:

要從前臺移除service,呼叫stopForeground()。這個方法有boolean型引數,表明是否也從狀態列刪除對應的通知.這個方法不會停掉service。然而,如果你停止了正在前臺執行的service,這個通知也會被刪除。
注意:方法startForeground()和方法stopForeground()是從Android2.0 (API Level 5)引入的。為了在早期版本是於前臺執行你的service,你必須使用以前的那個setForeground()方法—見startForeground()的API文件檢視如何提供與舊版本的相容性。

管理Service的生命期

一個service的生命期比一個activity要簡單得多。然而,你依然需要密切關注你的service是如何被建立又是如何被銷燬的,因為一個service可以運行於後臺而使用者看不到它。
ervice的生命期—從它被建立到它被銷燬—有兩條路可走:

一個"啟動的"service

在其它元件呼叫startService()時建立。然後service就長期執行並且必須呼叫stopSelf()自己停止自己。另一個元件也可以呼叫stopService()來停止它。當service停止後,系統就銷燬它。

一個繫結的service

當另一個元件(一個客戶端)呼叫bindService()時建立。然後客戶端通過一個IBinder介面與service通訊。以呼叫unbindService()停止通訊。多個客戶端可以繫結到同一個service並且當所有的客戶端都解除繫結後,系統就銷燬掉這個service。(service不需停止自己。)
這兩條路並不是完全分離的。也就是,你是可以繫結到用startService()啟動的service的。例如,一個後臺音樂service在通過傳入指明要播放的音樂的intent來呼叫startService()後啟動。之後,當用戶想對播放器進行一些操作或要獲取當前歌曲的資訊時,一個activity可以通過呼叫bindService()繫結到service。在此情況下,stopService()或stopSelf()不會真正的停止service,除非所有的客戶端都取消綁定了

實現生命期回撥方法

就像activity,service也具有生命期回撥方法,用它們你可以監視service的狀態的變化並且在合適的時機做一些工作。下面的框架程式碼演示了每個生命期方法的實現:
import android.app.Service;

import android.content.Intent;

import android.os.IBinder;

public class ExampleService extends Service {

int mStartMode; // 表明在service被殺後的行為

IBinder mBinder; // 客戶端繫結到的介面

boolean mAllowRebind; // 表明onRebind是否應被使用

@Override

public void onCreate() {

// The service is being created

}

@Override

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

// service 正在啟動,在呼叫startService()期間被呼叫

return mStartMode;

}

@Override

public IBinder onBind(Intent intent) {

// 一個客戶端通過bindService()繫結到這個service

return mBinder;

}

@Override

public boolean onUnbind(Intent intent) {

// 所有的客戶端使用unbindService()解除了繫結

return mAllowRebind;

}

@Override

public void onRebind(Intent intent) {

// 一個客戶端在呼叫onUnbind()之後,正使用bindService()繫結到service

}

@Override

public void onDestroy() {

// service不再被使用並將被銷燬

}

}

注:不像activity的生命期回撥方法們,你不需要呼叫父類的相應實現
通過實現這些方法們,你可以監視service生命期的兩個巢狀迴圈:
service的一生介於呼叫onCreate()的時間和onDestroy()返回的時間。就像activity,service在onCreate()中做初始化工作並且onDestroy()中釋放所有資源。例如,一個音樂播放service可以在onCreate()中建立音樂播放的執行緒,之後在onDestroy()中停止這個執行緒。
onCreate()和onDestroy()方法被所有的service呼叫,不管它們通過startService()還是bindService()建立。
service的活動生命期開始於onStartCommand()或onBind()被呼叫時.每個方法各自處理傳入的Intent。
如果service是"啟動的",活動生命期就結束於整個生命期的結束時(即使onStartCommand()返回後,service依然處於活動狀態)。如果是一個繫結的service,它的活動生命期在onUnbind()返回後結束。
注:儘管一個"啟動的"service在呼叫stopSelf()或stopService()時結束,但並沒有單獨的回撥對應這些停止方法(沒有類似於onStop()的回撥)。所以,除非service被繫結到一個客戶端,系統就會在停止時銷燬service—onDestroy()是唯一收到的回撥。
但記住任何service,不管它是怎樣啟動的,都是可能允許繫結的。所以一個從onStartCommand()啟動的service(客戶端呼叫了startService())仍可以接收onBind()呼叫(當客戶端呼叫bindService()時)。