کانال بله, جهت پشتیبانی و اطلاع رسانی کانال بله, جهت پشتیبانی و اطلاع رسانی
عضویت

زمانبندی task ها در اندروید

زمانبندی task ها در اندروید-android

در این فصل از مقاله ی آموزشی به نحوه ی زمان بندی تسک ها در محیط اندروید می پردازیم . همچنین تشریح جامعی در باب رابط های برنامه سازی کاربردی AlarmManager و Jobscheduler در اختیار شما قرار می دهیم.

فهرست محتوا

1. زمان بندی تسک ها

  • از چه روشی برای انجام زمان بندی تسک ها نباید استفاده کرد
  • چه گزینه های برای زمان بندی تسک ها در اختیار داریم ؟

2. زمان بندی تسک ها با استفاده از سرویس alarm manager

  • Alarm manager چیست و چگونه می توان به آن دسترسی پیدا کرد ؟
  • زمان بندی تسک ها به وسیله ی سرویس خود سیستم AlarmManager
  • معایب استفاده از سرویس AlarmManager

3. استفاده از JobScheduler به منظور زمان بندی برنامه های پس زمینه

  • رابط برنامه سازی کاربردی jobScheduler (API)
  • نکات مثبت و مزایای jobScheduler (API)
  • ایجاد برنامه

4. تمرین : استفاده از JobScheduler برای زمان بندی برنامه های پس زمینه (background jobs)

  • مقصود از این تمرین
  • ایجاد پروژه
  • ایجاد فایل طرح بندی (layout)
  • ایجاد JobService
  • ایجاد activity آزمایشی

زمان بندی تسک ها

از چه روشی برای انجام زمان بندی تسک ها نباید استفاده کرد

اگر در برنامه ی خود activity یا سرویسی دارید که مجبور است یک تسک تکراری را انجام دهد, نمی توان به یک TimerTask یا مواردی مشابه آن تکیه کرد و آن را از مولفه های اندروید کنترل و مدیریت کرد .
سیستم اندروید این اجازه را دارد که activity ها و سرویس ها را هر زمانی که احساس کرد به منابع اشغال شده توسط آن ها برای کار دیگری نیاز دارد ناگهان پایان دهد, تا از این طریق منابع مورد نیاز آزاد شده و مورد استفاده ی کار مورد نظر قرار گیرد .
بنا به دلایل ذکر شده تکه کد زیر کاملاً نادرست و غلط محسوب می شود .

public void onCreate() {
    super.onCreate();
    pollForUpdates();
  }
 
// WRONG, don't do this
private void pollForUpdates() {
  timer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
      if (list.size() >= 6) {
        list.remove(0);
      }
      list.add(fixedList[index++]);
      if (index >= fixedList.length) {
        index = 0;
      }
    }
  }, 0, UPDATE_INTERVAL);
  Log.i(getClass().getSimpleName(), "Timer started.");
}  

چه گزینه های برای زمان بندی تسک ها در اختیار داریم ؟

در حال حاضر سیستم اندروید دو وسیله و روش اصلی برای زمان بندی تسک ها دارد که به آن ها در زیر خواهیم پرداخت .

زمان بندی تسک ها با استفاده از سرویس alarm manager

Alarm manager چیست و چگونه می توان به آن دسترسی پیدا کرد ؟

عبارتند از یک سرویس متعلق به خود سیستم که توسط کلاس AlarmManager پیاده سازی می شود . دستیابی به سرویس نام برده با فراخوانی متد (AlarmManager) getSystemService(Context.ALARM_SERVICE) امکان پذیر می باشد.

زمان بندی تسک ها به وسیله ی سرویس خود سیستم AlarmManager ,

به منظور زمان بندی تسک های تکراری برنامه نویس می تواند از alarm manager system service کمک بگیرد . با استفاده از این سرویس می توان, به عنوان مثال, اجرای سرویس ها را زمان بندی کند .
کد ذیل نحوه ی انجام این کار را برای شما به نمایش می گذارد .

Calendar cal = Calendar.getInstance();
Intent intent = new Intent(this, MyService.class);
PendingIntent pintent = PendingIntent.getService(this, 0, intent, 0);
 
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// schedule for every 30 seconds
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 30*1000, pintent); 

همان طور که در کد ذیل مشاهده می کنی, بار دیگر متسلزم به استفاده از alarm manager system service هستید .

// Restart service every 30 seconds
  private static final long REPEAT_TIME = 1000 * 30;
@Override
public void onReceive(Context context, Intent intent) {
  AlarmManager service = (AlarmManager) context
    .getSystemService(Context.ALARM_SERVICE);
  Intent i = new Intent(context, MyStartServiceReceiver.class);
  PendingIntent pending = PendingIntent.getBroadcast(context, 0, intent,
    PendingIntent.FLAG_CANCEL_CURRENT);
  Calendar cal = Calendar.getInstance();
  // Start 30 seconds after boot completed
  cal.add(Calendar.SECOND, 30);
  //
  // Fetch every 30 seconds
  // InexactRepeating allows Android to optimize the energy consumption
  service.setInexactRepeating(AlarmManager.RTC_WAKEUP,
    cal.getTimeInMillis(), REPEAT_TIME, pending);
  // service.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
  // REPEAT_TIME, pending);
} 

معایب استفاده از سرویس AlarmManager

Alarm manager به خودی خود از وضعیت جاری دستگاه آگاهی یا اطلاعی ندارد, برای مثال, توجه نمی کند که آیا دستگاه به پریز برق وصل است یا در حال انجام کار خاصی نیست یا به شبکه وصل است و غیره....
برای حل مشکلاتی از این دست, اندروید رابط برنامه سازی کاربردی (API) JobScheduler را در ویرایش 5.0 اندروید (معادل API 21) معرفی و کاربردی کرد .

استفاده از JobScheduler به منظور زمان بندی برنامه های پس زمینه

رابط برنامه سازی کاربردی jobScheduler (API)

نسخه ی 5.0 اندروید که به Lollipop نیز معروف می باشد رابط برنامه سازی کاربردی job scheduler (زمان بندی برنامه ها) را در قالب کلاس JobScheduler ارائه می دهد که در صورت در دسترس بودن منابع کافی به سیستم امکان می دهد برنامه ها را گروه بندی کند . برنامه هایی که توسط این API زمان بندی می شوند عبارتند از تسک هایی که برای کاربر نمایش داده نمی شوند, تسک هایی که آن دسته از داده های کاربر را که به زمان زیاد و مشخصی برای آپلود نیاز نداشته و چندان ضروری نیستند یا دانلود داده هایی از این دست . به عبارتی دیگر, همه ی چیزهایی که باید در زمان معینی انجام شوند, اما از سوی دیگر از اهمیت چندانی برای کاربر برخوردار نیستند .

نکات مثبت و مزایای jobScheduler (API)

در مقایسه با SyncAdapter سفارشی و یا alarm manager, JobScheduler از امکان زمان بندی دسته ای پشتیبانی می کند, و آن بدین معنا است که به منظور صرفه جویی در مصرف باتری دستگاه, این تابع کارهایی را باید انجام شود را باهم ترکیب و گروه بندی کرده و یکجا انجام می دهد . JobManager نیز اداره و مدیریت آپلود ها را به مراتب ساده تر ساخته, از جمله ی آن می توان رفع خودکار مشکلاتی از قبیل غیر قابل اطمینان یا نامعتبر بودن شبکه, و بازآغازی غیر ضروری و ناخواسته ی برنامه ی کاربردی را نام برد.
ذیل نمونه هایی از کاربرد JobManager برای شما فهرست شده :

  • تسک هایی که تنها زمانی باید انجام شوند که دستگاه به یک منبع تغذیه متصل است
  • تسک هایی که حتماً نیازمند دسترسی به شبکه یا اتصال به wi-fi هستند
  • تسک هایی که چندان ضروری نیستند
  • تسک هایی که باید به طور منظم گروهی یا دسته ای اجرا شوند, زیرا که زمان انجام آن ها چندان تفاوتی نمی کند

ایجاد برنامه

یک واحد کار در شئ JobInfo کپسوله سازی می شود . این شئ است که معیارهای زمان بندی و برنامه ریزی را مشخص می کند .
زمان بند (برنامه ریز) کارها (یا همان job scheduler) از حالتی که دستگاه در آن قرار دارد از جمله حالت استراحت یا غیر فعال و همچنین اینکه آیا دسترسی به شبکه در حال حاضر امکان پذیر است یا خیر کاملاً مطلع است .
با استفاده از کلاس JobInfo.Builder برنامه نویس می تواند با پیکربندی دلخواه تعیین کند که تسک برنامه ریزی شده چگونه باید اجرا و راه اندازی شود . برنامه نویس این امکان را دارد که تسک ها را طوری برنامه ریزی کند که فقط تحت شرایط خاصی انجام شوند :

  • زمانی که دستگاه در حال شارژ شدن می باشد
  • دستگاه به شبکه با اینترنت نامحدود وصل است
  • دستگاه غیرفعال است
  • پیش از آخرین مهلت آغاز شود
  • طی یک برهه ی زمانی از پیش تعیین شده برای مثال طی یک ساعت آینده راه اندازی شود
  • تسک پس از یک تاخیر جزئی راه اندازی شود, برای مثال به مدت 10 دقیقه صبر کند سپس اجرا شود

این محدودیت ها را می توان با هم ترکیب کرد, برای مثال, یک کار یا برنامه را طوری زمان بندی و برنامه ریزی کرد که هر 20 دقیقه یکبار و هنگامی که دستگاه به شبکه ای با اینترنت نامحدود متصل است اجرا شود .
جهت راه اندازی کار معین, کلاس JobService را به ارث برده, سپس دو توابع onStartJob و onStopJob را پیاده سازی کنید . چنانچه کار (برنامه) مذکور بنا به هر دلیلی با شکست مواجه شد, در آن صورت مقدار true را از متد onStartJob برگردانده تا کار مورد نظر مجدداً راه اندازی شود . تابع onStartJob در نخ اصلی اجرا می شود, حال اگر پردازش ناهمگام را در متد نام برده راه اندازی کنید, true (مقدار صحیح) بازگردانده می شود و در غیر این صورت false .

تمرین : استفاده از JobScheduler برای زمان بندی برنامه های پس زمینه (background jobs)

مقصود از این تمرین

در این تمرین به ساخت یک نمونه برنامه ی کوچک ویژه ی زمان بندی کارها از طریق رابط برنامه سازی کاربردی JobScheduler که در API 21 معرفی شد می پردازیم .

استفاده از JobScheduler برای زمان بندی برنامه های پس زمینه (background jobs)

ایجاد پروژه

پروژه ی جدید اندرویدی به نام com.vogella.android.jobscheduler مبتنی بر API 21 ایجاد کنید .

ایجاد فایل طرح بندی (layout)

جدیدی مشابه ذیل ایجاد کنید . Layout file




                
                

                
                
                

                
                

                

               
           
                
                

                

                

                

                

           
                
                

                

           
                
                

                

           
       
                

                

   

ایجاد JobService

سرویس زیر را به همراه پیاده سازی زیر ایجاد کنید .

package com.vogella.android.jobscheduler;
import java.util.LinkedList;
import android.app.job.JobInfo;
import android.app.job.JobParameters;
import android.app.job.JobScheduler;
import android.app.job.JobService;
import android.content.Context;
import android.content.Intent;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
/**
 * JobService to be scheduled by the JobScheduler. Requests scheduled with
 * the JobScheduler ultimately land on this service's "onStartJob" method.
 * Currently all this does is write a log entry
 */
public class TestJobService extends JobService {
  private static final String TAG = "SyncService";
  @Override
  public boolean onStartJob(JobParameters params) {
    // We don't do any real 'work' in this sample app. All we'll
    // do is track which jobs have landed on our service, and
    // update the UI accordingly.
    Log.i(TAG, "on start job: " + params.getJobId());
    return true;
  }
  @Override
  public boolean onStopJob(JobParameters params) {
    Log.i(TAG, "on stop job: " + params.getJobId());
    return true;
  }
 
  MainActivity mActivity;
  private final LinkedList jobParamsMap = new LinkedList();
 
  public void setUiCallback(MainActivity activity) {
    mActivity = activity;
  }
 
} 

از ثبت آن در مانیفست اندروید اطمینان حاصل کنید .

ایجاد activity آزمایشی

پیاده سازی activity خود را مشابه کد زیر تغییر دهید .

package com.vogella.android.jobscheduler;
 
import android.app.Activity;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.RadioButton;
public class MainActivity extends Activity {
  public static final int MSG_UNCOLOUR_START = 0;
  public static final int MSG_UNCOLOUR_STOP = 1;
  public static final int MSG_SERVICE_OBJ = 2;
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Resources res = getResources();
    defaultColor = res.getColor(R.color.none_received);
    startJobColor = res.getColor(R.color.start_received);
    stopJobColor = res.getColor(R.color.stop_received);
    mDelayEditText = (EditText) findViewById(R.id.delay_time);
    mDeadlineEditText = (EditText) findViewById(R.id.deadline_time);
    mWiFiConnectivityRadioButton = (RadioButton) findViewById(R.id.checkbox_unmetered);
    mAnyConnectivityRadioButton = (RadioButton) findViewById(R.id.checkbox_any);
    mRequiresChargingCheckBox = (CheckBox) findViewById(R.id.checkbox_charging);
    mRequiresIdleCheckbox = (CheckBox) findViewById(R.id.checkbox_idle);
    mServiceComponent = new ComponentName(this, TestJobService.class);
      }
  // UI fields.
  int defaultColor;
  int startJobColor;
  int stopJobColor;
  private EditText mDelayEditText;
  private EditText mDeadlineEditText;
  private RadioButton mWiFiConnectivityRadioButton;
  private RadioButton mAnyConnectivityRadioButton;
  private CheckBox mRequiresChargingCheckBox;
  private CheckBox mRequiresIdleCheckbox;
  ComponentName mServiceComponent;
  /** Service object to interact scheduled jobs. */
  TestJobService mTestService;
  private static int kJobId = 0;
 
/**
   * UI onclick listener to schedule a new job. 
   */
  public void scheduleJob(View v) {
    JobInfo.Builder builder = new JobInfo.Builder(kJobId++,mServiceComponent);
    String delay = mDelayEditText.getText().toString();
    if (delay != null && !TextUtils.isEmpty(delay)) {
      builder.setMinimumLatency(Long.valueOf(delay) * 1000);
    }
    String deadline = mDeadlineEditText.getText().toString();
    if (deadline != null && !TextUtils.isEmpty(deadline)) {
      builder.setOverrideDeadline(Long.valueOf(deadline) * 1000);
    }
    boolean requiresUnmetered = mWiFiConnectivityRadioButton.isChecked();
    boolean requiresAnyConnectivity = mAnyConnectivityRadioButton
        .isChecked();
    if (requiresUnmetered) {
      builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
    } else if (requiresAnyConnectivity) {
      builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
    }
    builder.setRequiresDeviceIdle(mRequiresIdleCheckbox.isChecked());
    builder.setRequiresCharging(mRequiresChargingCheckBox.isChecked());
    JobScheduler jobScheduler =
            (JobScheduler) getApplication().getSystemService(Context.JOB_SCHEDULER_SERVICE);
        jobScheduler.schedule(builder.build());
  }
  public void cancelAllJobs(View v) {
    JobScheduler tm = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
    tm.cancelAll();
  }
}  
1394/08/11 8396 3133
رمز عبور : tahlildadeh.com یا www.tahlildadeh.com
نظرات شما

نظرات خود را ثبت کنید...