Android Service 詳解三:從類Service派生service

openkk 12年前發布 | 21K 次閱讀 Android Android開發 移動開發

從類Service派生

  如你在上節所見,使用類IntentService使得你實現一個"開始的"service非常容易.然而,如果你需要你的service以多線程方式執行(而不是使用工作隊列),那么你需要從類Service派生來處理每個intent



  相比之下,下面的例子從類Service派生并實現了與上面使用IntentService例子完全相同的工作.也就是在一個線程中序列化的處理每個"開始"請求.

 public class HelloService extends Service {
  private Looper mServiceLooper;
  private ServiceHandler mServiceHandler;

// 處理從線程收到的消息們 private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { // 通常我們在這里做一些工作比如下載一個文件 // 在我們的例子中,僅僅是睡5秒鐘. long endTime = System.currentTimeMillis() + 5*1000; while (System.currentTimeMillis() < endTime) { synchronized (this) { try { wait(endTime - System.currentTimeMillis()); } catch (Exception e) { } } } // 使用startId停止服務,從而使我們不會在處理 // 另一個工作的中間停止service stopSelf(msg.arg1); } }

@Override public void onCreate() { // 啟動運行service的線程.注意我創建了一個 // 分離的線程,因為service通常都是在進程的 // 主線程中運行,但我們不想讓主線程阻塞.我們還把新線程 // 搞成后臺級的優先級,從而減少對UI線程(主線程的影響). HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND); thread.start();

// Get the HandlerThread's Looper and use it for our Handler 
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);

}

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

  // 對于每個開始請求,發送一消息來開始一次工作,并且把
  // start ID也傳過去,所以當完成一個工作時,我們才知道要停止哪個請求.
  Message msg = mServiceHandler.obtainMessage();
  msg.arg1 = startId;
  mServiceHandler.sendMessage(msg);

  // 如果我們在這里返回后被被殺死了,重啟之.
  return START_STICKY;

}

@Override public IBinder onBind(Intent intent) { // We don't provide binding, so return null return null; }

@Override public void onDestroy() { Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show(); } } </pre>  如你所見,要做的工作比使用IntentService時多一些.</span>



  然而,因為你自己處理每次對onStartCommand()的調用,你可以同時執行多個請求.這個例子并沒有那樣做,但是如果那是你所需要的,那么你可以為每個請求創建一個新的線程并且立即運行它們(而不是等待上一個請求完成)



  注意方法onStartCommand()必須返回一個整數.這個整數描述了在系統殺死它的事件中系統如何繼續這個服務(如前面所述,IntentService的默認實現為你處理這些,當然你也能夠去改寫它)onStartCommand()也返回值必須是下面常量之一:

  • START_NOT_STICKY

      如果系統在onStartCommand()返回后殺死了服務,不要重新創建這個service,除非還有掛起的intent需要被傳送.這是避免在不必要時運行你的service和當你的應用可以簡單重啟任何未竟的工作時的最佳選擇.

    </li>

  • START_STICKY

      如果系統在onStartCommand()返回后殺死了這個service,會重新創建這個service并且調用onStartCommand(),但是不再重新發送上次最后一個intent,而是使用一個nullintent調用onStartCommand(),除非有一些掛起的intent,在此情況下,這些掛起的intent被派送.這適合于媒體播放器(or或相似也的服務),它不執行命令,但是無限期的運行并等待一個工作.

    </li>

  • START_REDELIVER_INTENT

      如果系統在onStartCommand()返回后殺死了service,重新創建這個service并且使用上次最后一個intent調用onStartCommand().任何掛起的intent都順序地被派送.這適合于活躍地執行一個工作并且應被立即恢復的服務,比如下載一個文件

    </li> </ul> 轉自:http://blog.csdn.net/nkmnkm/article/details/7322200

 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!