星期五, 9月 16, 2011

Service(四)

Android

Service(四)

在之前的筆記中學過,service分成兩種形式,一為started另一為bound,今天就試著來學學如何實現一個started形式的service。

Create a started service
一個started service是其他組件藉著呼叫startService()方法來啟動,導致調用service的onStartCommand()方法。

當service啟動,它會擁有一個與啟動它的組件無關且獨立的生命週期,而且service能無限地在後台運行,甚至啟動它的組件已經被銷毀,它還是能繼續運行。當service工作完成時,service應該調用StopSelf()停止自己,或者其他組件可以調用stopService()來停止service。

一個應用程式組件(比如activity)能藉著呼叫startService()方法啟動service,並且傳遞Intent物件指定啟動哪一個service組件以及傳遞任何該service用到的數據。該service會在onStartCommand()方法中接收Intent物件。

傳統來說有兩種類別你可以繼承來產生started的service:
Service
此類別是所有service的基本,當繼承了此類別,創造一個新的執行續來執行service的所有工作是一件重要的事,因為service使用了應用程式的main執行續,就可能減慢了應用程式中任何activity的運行。

IntentService
此類為service類別的子類,使用worker thread來處理所有的啟動請求,一次一個。如果你不需要你的service同時處理多個請求,這是最佳的方式。所有你需要做的就是實現onHandleIntent()方法,它可以接收所有啟動要求。


那接下來就來一一學習繼承Service類別與r繼承IntentService類別該如何實現started形式的service。首先是繼承IntnetService類別。

Extending the IntentService class
因為大部分的started service不需要同時處理多個請求,你使用IntentService()實現service可能是最好的選擇。

以下實作IntentService:

  • 產生一個與應用程式的主執行續分開的預設worker thread,並執行傳給onStartCommand()的所有Intent物件。
  • 產生一個工作佇列且一次傳遞一個intent物件給onHandleIntent()方法執行,所以你不必擔心多工的問題。
  • service在所有啟動請求都已處理完後停止,所以你無須呼叫stopSelf()方法。
  • 提供回傳null的預設onBind()方法。
  • 提供預設onStartCommand(0方法來寄送Intent物件到工作佇列中,並且在onHandleIntent()方法中執行工作。

public class HelloIntentService extends IntentService {

  /** 
   * A constructor is required, and must call the super IntentService(String)
   * constructor with a name for the worker thread.
   */
  public HelloIntentService() {
      super("HelloIntentService");
  }

  /**
   * The IntentService calls this method from the default worker thread with
   * the intent that started the service. When this method returns, IntentService
   * stops the service, as appropriate.
   */
  @Override
  protected void onHandleIntent(Intent intent) {
      // Normally we would do some work here, like download a file.
      // For our sample, we just sleep for 5 seconds.
      long endTime = System.currentTimeMillis() + 5*1000;
      while (System.currentTimeMillis() < endTime) {
          synchronized (this) {
              try {
                  wait(endTime - System.currentTimeMillis());
              } catch (Exception e) {
              }
          }
      }
  }
}
在這裡你所需要的是一個建構式以及實現onHandleIntent(Intent intent)方法。
如果你決定複寫其他回呼方法,比如onCreate()、onStartCommand()、onDestroy(),如此,IntentService就可以正確地處理worker thread的生命週期。

例如,onStartCommand()必須回傳預設的執行結果(此例子告訴我們intent物件是如何傳遞到onHandleIntent()方法的)。

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
    return super.onStartCommand(intent,flags,startId);
}

除了onHandleIntent()之外,唯一你不需要呼叫super class的就是onBind()方法(但是你只需要在你的service允許綁定時實現onBind()方法)。


沒有留言:

張貼留言