Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 四大組件之Service(二)-Service在各種情況下的生命周期

四大組件之Service(二)-Service在各種情況下的生命周期

編輯:關於Android編程

第3節 Service的生命周期

3.1 Service的生命狀態

Activity類似,Service也是有生命周期的。在實現一個Service的時候,可以覆蓋它的生命周期函數,當它進入不同生命狀態的時候,這些函數會被觸發,我們就可以在它不同的生命階段做不同的邏輯操作。

public class MyService extends Service {
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    @Override
    public void onRebind(Intent intent) {
        super.onRebind(intent);
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

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

因為Service不像Activity有需要顯示的界面,所以它的狀態少了很多,沒有onResume() onPause()等等與界面顯示相關的狀態。

這裡面的onStartCommand()函數與onUnbind()函數要特別注意,它們的返回值有特別的意義,會影響到Service的生命周期,我們會在最後單獨解釋。

3.2 生命周期

通過startService()運行的Service與通過bindService()運行的Service相比較,它們的生命周期有所不同。

假設Service-MyService 還沒有被啟動過,我們來看看它被一個或多個組件使用startService() stopService() bindService() unbindService()這些方法後,生命周期會怎麼變化。

組件名稱 啟動Service的方法 關閉Service的方法 A startService() stopService() B startService() stopService() C bindService() unbindService() D bindService() unbindService()

3.2.1 Start Service的生命周期

對於只使用startService()stopService()來控制Service的情況:

情況1

A -- startService() ->
MyService -- onCreate() ->
MyService -- onStartCommand() ->

A -- stopService() ->
MyService -- onDestroy()

情況2

A -- startService() ->
MyService -- onCreate() ->
MyService -- onStartCommand() ->

A -- startService() ->
MyService -- onStartCommand() ->

A -- stopService() ->
MyService -- onDestroy()

情況3

A -- startService() ->
MyService -- onCreate() ->
MyService -- onStartCommand() ->

B -- startService() ->
MyService -- onStartCommand() ->

A -- stopService() ->
MyService -- onDestroy()

情況4

A -- startService() ->
MyService -- onCreate() ->
MyService -- onStartCommand() ->

B -- startService() ->
MyService -- onStartCommand() ->

B -- stopService() ->
MyService -- onDestroy()

可以看出,

任意組件調用startService()後,如果這個Service還沒有創建,系統會首先創建-onCreate()

之後觸發onStartCommand()

任意組件調用stopService()後,如果這個Service還沒有被銷毀,系統會銷毀-onDestroy()

3.2.2 Bind Service的生命周期

onStartCommand()函數與onUnbind()函數也會對生命周期有影響,所以這裡我們假設使用的是默認的返回值,

@Override
public boolean onUnbind(Intent intent) {
    //實際上是返回false
   return super.onUnbind(intent);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    //實際上是返回START_STICKY
   return super.onStartCommand(intent, flags, startId);
}

組件觸發Service運行的startService()函數也會對生命周期有影響--第三個參數,所以這裡我們假設使用Context.BIND_AUTO_CREATE

bindService(i, mServiceConnection, Context.BIND_AUTO_CREATE);

那麼,對於只使用bindService()unbindService()來控制Service的情況:

情況1

C -- bindService() ->
MyService -- onCreate() ->
MyService -- onBind() ->
C -- onServiceConnected()被觸發 ->

C -- unbindService() ->
MyService -- onUnbind()
MyService -- onDestroy()

情況2

C -- bindService() ->
MyService -- onCreate() ->
MyService -- onBind() ->
C -- onServiceConnected()被觸發 ->

C -- bindService() ->
MyService -- 無變化

C -- unbindService() ->
MyService -- onUnbind()
MyService -- onDestroy()

情況3

C -- bindService() ->
MyService -- onCreate() ->
MyService -- onBind() ->
C -- onServiceConnected()被觸發 ->

D -- bindService() ->
MyService -- onBind() ->
D -- onServiceConnected()被觸發 ->

C -- unbindService() ->
MyService -- onUnbind()

D -- unbindService() ->
MyService -- onUnbind()
MyService -- onDestroy()

情況4

C -- bindService() ->
MyService -- onCreate() ->
MyService -- onBind() ->
C -- onServiceConnected()`被觸發 ->

D -- bindService() ->
MyService -- onBind() ->
D -- onServiceConnected()被觸發 ->

D -- unbindService() ->
MyService -- onUnbind()

C -- unbindService() ->
MyService -- onUnbind()
MyService -- onDestroy()

可以看出,

任意組件調用bindService()後,如果這個Service還沒有創建,系統會首先創建-onCreate()

之後觸發onBind()

之後組件的onServiceConnected()被觸發,告知綁定成功;

任意已綁定的組件調用unbindService()後,會觸發onUnbind()

如果這個Service沒有與其他的組件綁定,那麼系統會銷毀-onDestroy()

3.2.3 混合模式下的生命周期

對於使用了startService() stopService()bindService()unbindService()等兩種方式來控制Service的情況:

情況1

A -- startService() ->
MyService -- onCreate() ->
MyService -- onStartCommand() ->

C -- bindService() ->
MyService -- onBind() ->
C -- onServiceConnected()被觸發 ->

C -- unbindService() ->
MyService -- onUnbind()

A -- stopService() ->
MyService -- onDestroy()

情況2

A -- startService() ->
MyService -- onCreate() ->
MyService -- onStartCommand() ->

C -- bindService() ->
MyService -- onBind() ->
C -- onServiceConnected()被觸發 ->

A -- stopService() ->
MyService -- 無變化

C -- unbindService() ->
MyService -- onUnbind()
MyService -- onDestroy()

情況3

C -- bindService() ->
MyService -- onCreate() ->
MyService -- onBind() ->
C -- onServiceConnected()被觸發 ->

A -- startService() ->
MyService -- onStartCommand() ->

C -- unbindService() ->
MyService -- onUnbind()

A -- stopService() ->
MyService -- onDestroy()

情況4

C -- bindService() ->
MyService -- onCreate() ->
MyService -- onBind() ->
C -- onServiceConnected()被觸發 ->

A -- startService() ->
MyService -- onStartCommand() ->

A -- stopService() ->
MyService -- 無變化

C -- unbindService() ->
MyService -- onUnbind()
MyService -- onDestroy()

可以看出,

當一個Service被創建-onCreate()之後;如果任意組件想要銷毀-onDestroy()這個Service;必須等到Service與它關聯的所有組件切斷聯系(通過stopService()或者unbindService())才行。

3.3 其它因素對生命周期的影響

Service生命周期的影響還有其它的因素。

3.3.1 unbind()函數返回值

自定義Service時,unbind()函數的返回值對Service的生命周期是有影響的。它會決定onRebind()函數是否被調用。

前面我們都看到了在unbind()返回falseService生命周期的變化。在unbind()返回true時,它的周期變化如下,

A -- startService() ->
MyService -- onCreate() ->
MyService -- onStartCommand() ->

C -- bindService() ->
MyService -- onBind() ->
C -- onServiceConnected()被觸發 ->

C -- unbindService() ->
MyService -- onUnbind()

C -- bindService() ->
MyService -- onRebind() ->
C -- onServiceConnected()被觸發 ->    
......

也就是說,假如一個Service正在運行,此時有個組件C要綁定它,那麼會觸發onBind()函數;如果C解除綁定,然後又再次綁定,那麼不會觸發onBind()而是觸發onRebind()函數。

3.3.2 bindService函數的參數

在綁定Service的時候,通常使用的Context.BIND_AUTO_CREATE參數,

bindService(i, mServiceConnection, Context.BIND_AUTO_CREATE);

如果不使用Context.BIND_AUTO_CREATE,那麼一個Service在沒有被運行起來之前,使用bindService()是不會讓Service自動運行起來的。

但是如果設置上了這個參數,那麼就會讓它運行起來,然後進行綁定。

除了Context.BIND_AUTO_CREATE參數,還有好些參數可以使用,

BIND_NOT_FOREGROUND,
BIND_ABOVE_CLIENT,
BIND_ALLOW_OOM_MANAGEMENT,
BIND_WAIVE_PRIORITY,
BIND_IMPORTANT,
BIND_ADJUST_WITH_ACTIVITY

可以用的方式同時使用其它的標志,例如,

bindService(i, mServiceConnection, Context.BIND_AUTO_CREATE|Context.BIND_NOT_FOREGROUND);

3.3.3 onStartCommand函數返回值

前面的onStartCommand()返回值使用的是START_STICKY,它對ServiceonStartCommand()和周期都是有影響的。

Service啟動之後,如果因為某種意外而停止運行(例如代碼寫的不好,Service直接崩潰了),那麼系統要自動的把這個Service再運行起來。這個時候,onStartCommand()的返回值就決定了Service重啟的行為,

START_STICKYService重啟(onCreate())之後,會觸發onStartCommand(),但是此時onStartCommand()的參數Intent會變成空值,

public class MyService extends Service {
    public MyService() {
    }

    ......

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if(intent == null) {
            //因為這個Service在onStartCommand()返回的是START_STICKY,所以異常退出後,傳入的`intent`是空值
        }
        return START_STICKY;
    }
}

START_NOT_STICKYService將不會被自動重啟,所以也就不會觸發onStartCommand()

START_REDELIVER_INTENTService重啟(onCreate())之後,會觸發onStartCommand(),此時onStartCommand()的參數Intent不會變成空值。該Intent將是以前想要啟動這個ServiceIntent;如果以前有多個Intent想要啟動它,那麼這裡會傳入最後一個,也就是最近的一個;

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved