Service ها در اندروید #۲

در پست قبل اشاره شد که سه نوع سرویس در اندروید وجود دارد.یکی از آن ها Startedها است.برای ساخت این نوع سرویس ها می توانیم از دو کلاس ارث بری کنیم:

  1. کلاس Service:کلاس پایه برای ساخت یک سرویس است و مهم است که در کلاس های مشتق شده یک thread مجزا ایجاد شود تا عملکرد کلی برنامه تحت تاثیر قرار نگیرد.
  2. کلاس IntentService:زمانیکه از این کلاس ارث بری می کنید نیازی نیست که یک thread مجزا ساخته شود.البته این نوع سرویس ها امکان مدیریت کردن چند درخواست همزمان را ندارند.

مثالی از پیاده سازی یک IntentService :

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.
      try {
          Thread.sleep(5000);
      } catch (InterruptedException e) {
          // Restore interrupt status.
          Thread.currentThread().interrupt();
      }
  }
}

توجه به این نکته ضروری است که در صورت پیاده سازی هر کدام از callbackهای onCreate(), onStartCommand(), یا onDestroy() باید کلاس super  فراخوانی شود مگر در  callback مربوط به onBind.

نمونه ای از پیاده سازی کلاس پایه Service

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.
          try {
              Thread.sleep(5000);
          } catch (InterruptedException e) {
              // Restore interrupt status.
              Thread.currentThread().interrupt();
          }
          // 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();
  }
}

onStartCommand() نیاز دارد که یک int برگردانده شود.این مقدار مشخص می کند که در صورت kill شدن سرویس توسط android چگونه باید ادامه کارش را انجام دهد.در این متد می توان از constهای زیر برای بازگشت استفاده کرد:

  • START_NOT_STICKY:در این حالت اگر سرویس kill شود دیگر ساخته نمی شود مگر اینکه pending intentی برای تحویل وجود داشته باشد.
  • START_STICKY:اگر سیستم اندروید سرویس را kill  کند در این حالت دوباره ساخته می شود و متد onStartCommand() دوباره فراخوانی خواهد شد ولی آخرین intent دریافتی را دوباره تحویل نخواهد داد.همچنین pending intentها را نیز دوباره تحویل خواهند داد.
  • START_REDELIVER_INTENT:مثل START_STICKY است با این تفاوت که آخرین intent را دوباره تحویل می دهد.این برای زمانی مثل دانلود فایل مناسب است.

توجه به این نکته ضروری است که باید بعد از اتمام کار سرویس حتما سرویس مورد نظر stop شود.

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *