Android Service—繼承Service類

來源:互聯網
上載者:User

繼承IntentService類來實現一個被啟動類型的服務很簡單,但是如果你需要服務執行多線程(而不是通過工作隊列來處理啟動請求),那麼你就要繼承Service類來處理每個Intent。

為便於比較,下面例子中,Service類的實現代碼執行了與之前“繼承IntentService類”一節中的例子相同的工作,也就是說,對於每個啟動請求,它都會使用一個背景工作執行緒來執行工作,並且每次只處理一個請求。

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

  // Handler that receives messages from the thread
  private final class ServiceHandler extends Handler {
      public ServiceHandler(Looper looper) {
          super(looper);
      }
      @Override
      public void handleMessage(Message msg) {
          // 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) {
                  }
              }
          }
          // Stop the service using the startId, so that we don't stop
          // the service in the middle of handling another job
          stopSelf(msg.arg1);
      }
  }

  @Override
  public void onCreate() {
    // Start up the thread running the service.  Note that we create a
    // separate thread because the service normally runs in the process's
    // main thread, which we don't want to block.  We also make it
    // background priority so CPU-intensive work will not disrupt our 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();

      // For each start request, send a message to start a job and deliver the
      // start ID so we know which request we're stopping when we finish the job
      Message msg = mServiceHandler.obtainMessage();
      msg.arg1 = startId;
      mServiceHandler.sendMessage(msg);
     
      // If we get killed, after returning from here, restart
      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();
  }
}

正如你看到的,它要比繼承IntentService類多做很多工作。

但是,因為你自己處理每個onStartCommand()方法的調用,你就能夠同時執行多個請求。在上面的例子中沒有這麼做,但是如果你想要這麼做的話,那麼你就能夠給每個請求建立一個新的線程,並且立即運行它們(而不是等待前一個請求完成)。

注意:onStartCommand()方法必須返回一個整數,這個整數是一個描述了在系統的殺死事件中,系統應該如何繼續這個服務的值(雖然你能夠修改這個值,但是IntentService處理還是為你提供了預設實現)。從onStartCommand()方法中返回的值必須是以下常量:

START_NOT_STICKY

如果系統在onStartCommand()方法返回之後殺死這個服務,那麼直到接受到新的Intent對象,這個服務才會被重新建立。這是最安全的選項,用來避免在不需要的時候運行你的服務。

START_STICKY

如果系統在onStartCommand()返回後殺死了這個服務,系統就會重新建立這個服務並且調用onStartCommand()方法,但是它不會重新傳遞最後的Intent對象,系統會用一個null的Intent對象來調用onStartCommand()方法,在這個情況下,除非有一些被發送的Intent對象在等待啟動服務。這適用於不執行命令的媒體播放器(或類似的服務),它只是無限期的運行著並等待工作的到來。

START_REDELIVER_INTENT

如果系統在onStartCommand()方法返回後,系統就會重新建立了這個服務,並且用發送給這個服務的最後的Intent對象調用了onStartCommand()方法。任意等待中的Intent對象會依次被發送。這適用於那些應該立即恢複正在執行的工作的服務,如下載檔案。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.