آموزشگاه برنامه نویسی تحلیل داده
آموزشگاه برنامه نویسی تحلیل داده

زمان بندی Taskها با AlarmManager و JobScheduler

دوره های مرتبط با این مقاله

این آموزش نحوه ی زمان بندی تسک ها در اندروید را با استفاده از توابع (API) JobScheduler تشریح می کند.

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

نحوه ی پیاده سازی

فرض کنید عملیاتی در برنامه اندرویدی خود دارید که بایستی بارها اجرا شود. در چنین شرایطی لازم است این را هم در نظر داشته باشید که سیستم اندروید ممکن است با توجه به شرایط activity ها و service ها را برای آزاد سازی منابع از حافظه حذف نماید. از این جهت نمی توانید برای زمان بندی تسک ها از کلاس های ساده ی محیط (platform) جاوا همچون TimerTask استفاده نمایید.

روش ها و ابزار مختلف زمان بندی تسک ها

سیستم اندروید دو ابزار برای زمان بندی اجرای تسک ها به شرح زیر ارائه می دهد:

  • AlarmManager (روش قدیمی)
  • JobScheduler API

اپلیکیشن های تحت موبایلی که امروزه برای محیط اندروید ساخته می شوند، برای زمان بندی و مدیریت اجرای تسک ها می بایست از توابع کتابخانه ای (API) JobScheduler استفاده نمایند. اپلیکیشن های تحت موبایل شما می توانند job ها را برای اجرا در زمان معین زمان بندی کرده، به سیستم اجازه دهند تا اجرای آن ها را بر اساس میزان حافظه، باتری و وضعیت اتصال مدیریت کند.

زمان بندی background task ها با استفاده از JobScheduler

توابع کتابخانه ای job scheduler

به طور کلی Job scheduler یک برنامه است که برای کنترل و مدیریت غیرحضوری برنامه‌هایی که در background سیستم اجرا می‌شوند (غالبا برای پردازش دسته‌ای)، مورد استفاده قرار می گیرد.
ویرایش 5.0 اندروید (API 21) توابع کتابخانه ای به نام job scheduler را در قالب کلاس JobScheduler در اختیار برنامه نویس قرار می دهد. API نام برده این امکان را فراهم می آورد تا هنگامی که منابعِ در اختیار سیستم به اندازه ی کافی رسید، job ها را به صورت دسته ای (batch) در پس زمینه به اجرا بگذارد. به بیان دیگر، توسعه دهنده می تواند با استفاده از این API تمامی کارهایی که از نظر زمان اجرا اهمیت چندانی برای کاربر ندارند را زمان بندی کند.

مزایای استفاده از JobScheduler

JobScheduler بر خلاف SyncAdapter اختصاصی یا alarm manager این قابلیت را دارد که job ها را برای پردازش دسته جمعی زمان بندی کند (آن ها را زمان بندی کرده و به هنگام رسیدن موعد تمامی کارها را دسته جمعی پردازش کند). در واقع JobScheduler با این کار (دسته بندی job ها برای پردازش دسته جمعی) میزان مصرف باتری را کاهش داده و کارایی کلی را بالا می برد.
یکی از مزایای استفاده از JobManager این است که مدیریت بارگذاری محتوا در وب را آسان ساخته و مسئله ی ناپایایی (unreliability) اینترنت را بر طرف می سازد. علاوه بر آن در صورت restart/بازآغازی، اپلیکیشن را طوری مدیریت می کند که خللی به وجود نیاید. برخی از موارد استفاده ی این JobScheduler را در زیر مشاهده می کنید:

  • تسک هایی که به هنگام متصل بودن دستگاه به منبع تغذیه بایستی اجرا شوند.
  • تسک هایی که برای اجرا نیاز به دسترسی به اینترنت یا Wi-Fi دارند.
  • تسک هایی که ضروری نیستند یا مستقیما با کاربر تعامل ندارند.
  • تسک هایی که زمان اجرای آن ها چندان اهمیتی ندارد و از این جهت می توان آن ها را گونه ای برنامه ریزی کرد که به صورت دسته جمعی و در زمان مشخصی در آینده اجرا شوند.

نحوه ی ایجاد یک Job

آبجکت JobInfo حامل اطلاعات ارسالی به JobScheduler بوده و کاملا پارامترهای مورد نیاز برای زمان بندی کارهایی که بر روی اپلیکیشن فراخواننده بایستی انجام شود را در خود کپسوله می کند.
به عبارت دیگر آبجکت JobInfo دربردارنده ی یک واحد کاری (unit of work) می باشد. این آبجکت مشخصات زمان بندی و کارهایی که باید انجام شود را تعیین می کند.
Job scheduler به شما این امکان را می دهد تا وضعیت دستگاه را بررسی کنید، برای مثال اینکه دستگاه بیکار است یا دسترسی به اینترنت در زمان مورد نظر امکان پذیر می باشد یا خیر و سپس بر اساس آن کارهای زمان بندی شده را انجام دهید.
جهت تعیین تنظیمات کارهای زمان بندی شده (محتوای کپسوله شده در آبجکت JobInfo) کافی است از کلاس JobInfo.Builder استفاده نمایید. می توانید تسک ها را طوری زمان بندی کنید که تحت شرایط خاصی اجرا می شود. این شرایط به شرح زیر هستند:

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

این محدودیت ها را می توان ترکیب کرد. برای مثال، می توانید یک job را به صورتی زمان بندی کنید که هر 20 دقیقه یکبار و هنگامی که دستگاه به اینترنت نامحدود وصل است اجرا شود. deadline یک تاریخ معین است که به عنوان محدودیت (constraint) زمانی اعمال شده و عملیات نهایتا تا زمان سر رسید آن باید انجام شود.
به منظور پیاده سازی یک job، می بایست کلاس JobService را به ارث برده (extend) و سپس توابع onStartJob و onStopJob را پیاده سازی نمایید. چنانچه job مورد نظر به هر دلیلی ناموفق بود، لازم است مقدار بولی true را از onStopJob برگردانید تا job ناموفق دوباره انجام شود. متد onStartJob در thread اصلی اجرا می شود، اگر پردازش ناهمزمان را در این متد آغاز کنید، در آن صورت می بایست مقدار بولی true و در غیر صورت false را برگردانید.

تمرین: زمان بندی background job ها با استفاده از JobScheduler

هدف تمرین

در تمرین حاضر، یک نمونه اپلیکیشن ساده می نویسید که job ها را با فراخوانی توابع کتابخانه ای (API) JobScheduler زمان بندی می کند.

ایجاد پروژه و فایل layout

یک پروژه ی جدید اندروید به نام com.vogella.android.jobscheduler بر اساس ورژن/API 21 کتابخانه های اندروید ایجاد نمایید.
حال فایل layout جدید ایجاد کنید که حداقل یک کنترل دکمه در آن تعریف شده باشد. سپس متد onClick را به property مربوطه ( onClick در لایه ی XML) تخصیص دهید.

ایجاد 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 call the "onStartJob" method
 */
public class TestJobService extends JobService {
        private static final String TAG = "SyncService";
        @Override
        public boolean onStartJob(JobParameters params) {
                // fake work
                Log.i(TAG, "on start job: " + params.getJobId());
                return true;
        }
        @Override
        public boolean onStopJob(JobParameters params) {
                return true;
        }
}
نکته:

لازم است سرویس را با استفاده از تگ service در لایه ی XML (فایل تنظیمات manifest ) تعریف نمایید.

ساخت 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 {
        TestJobService testService;
        private static int kJobId = 0;
        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
        }
        public void onClick(View v) {
                ComponentName mServiceComponent = new ComponentName(this, TestJobService.class);
                JobInfo.Builder builder = new JobInfo.Builder(kJobId++, serviceComponent);
                builder.setMinimumLatency(5 * 1000); // wait at least
                builder.setOverrideDeadline(50 * 1000); // maximum delay
              builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED); // require unmetered network
                builder.setRequiresDeviceIdle(true); // device should be idle
                builder.setRequiresCharging(false); // we don't care if the device is charging or not
                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();
        }
}

تمرین: فراخوانی JobScheduler از داخل یک receiver/راه اندازی و اجرای یک job <- service از طریق receiver

هدف از تمرین

در این تمرین به صورت کاملا کاربردی خواهید آموخت چگونه می توان یک job را که داخل receiver تعریف شده، با اتفاق افتادن رخداد خاصی (که receiver به آن گوش می دهد) فعال نمایید.

ایجاد receiver

Receiver را به صورت زیر پیاده سازی کنید.

package com.example.android.rssreader;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
public class BootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        ComponentName serviceComponent = new ComponentName(context, MyJobService.class);
        JobInfo.Builder builder = new JobInfo.Builder(0, serviceComponent);
        builder.setMinimumLatency(5 * 1000); // wait at least
        builder.setOverrideDeadline(50 * 1000); // maximum delay
        builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED); // require unmetered network
        builder.setRequiresDeviceIdle(true); // device should be idle
        builder.setRequiresCharging(false); // we don't care if the device is charging or not
        JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
        jobScheduler.schedule(builder.build());
    }
}

ایجاد Job

package com.example.android.rssreader;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.Intent;
/**
 * Created by vogella on 30.06.16.
 */
public class MyJobService extends JobService {
    @Override
    public boolean onStartJob(JobParameters params) {
        String url = params.getExtras().getString(RssApplication.URL);
        Intent i = new Intent(this, RssDownloadService.class); // starts the RssDownloadService service
        i.putExtra(RssApplication.URL, url); // some extra data for the service
        startService(i);
        return false; // true if we're not done yet
    }
    @Override
    public boolean onStopJob(JobParameters params) {
        // true if we'd like to be rescheduled
        return true;
    }
}

می توانید receiver (گوش دهنده به رخدادها) را برای event خاصی همچون رخداد boot و بالا آمدن سیستم ثبت و معرفی نمایید. event مذکور receiver مربوطه را از اتفاق مورد نظر با خبر نموده که آن خود job ای که سرویس اختصاصی را اجرا می کند، فعال می نماید.

  • 3677
  •    1532
  • تاریخ ارسال :   1395/12/08

دانلود PDF دانشجویان گرامی اگر این مطلب برای شما مفید بود لطفا ما را در GooglePlus محبوب کنید
رمز عبور: tahlildadeh.com یا www.tahlildadeh.com
ارسال دیدگاه نظرات کاربران
شماره موبایل دیدگاه
عنوان پست الکترونیک

ارسال

آموزشگاه برنامه نویسی تحلیل داده
آموزشگاه برنامه نویسی تحلیل داده

تمامی حقوق این سایت متعلق به آموزشگاه تحلیل داده می باشد .