انتقال از GCMNetworkManager به WorkManager

این سند توضیح می‌دهد که چگونه برنامه‌ها را برای استفاده از کتابخانه کارخواه WorkManager به‌جای کتابخانه GCMNetworkManager برای انجام عملیات پس‌زمینه انتقال دهید. روش ترجیحی برای زمان‌بندی کارهای پس‌زمینه توسط برنامه، استفاده از WorkManager است. با گنجاندن کتابخانه WorkManager GCM، می‌توانید WorkManager را فعال کنید تا از GCM برای زمان‌بندی تکالیف هنگام اجرا در دستگاه‌های Android با سطح API‏ ۲۲ یا پایین‌تر استفاده کند.

انتقال به WorkManager

اگر برنامه‌تان درحال‌حاضر از GCMNetworkManager برای انجام عملیات پس‌زمینه استفاده می‌کند، این مراحل را برای انتقال به WorkManager دنبال کنید.

برای مراحل زیر، فرض می‌کنیم که با کد GCMNetworkManager زیر شروع می‌کنید که تکلیف شما را تعریف و زمان‌بندی می‌کند:

کاتلین

val myTask = OneoffTask.Builder()
    // setService() says what class does the work
    .setService(MyUploadService::class.java)
    // Don't run the task unless device is charging
    .setRequiresCharging(true)
    // Run the task between 5 & 15 minutes from now
    .setExecutionWindow(5 * DateUtil.MINUTE_IN_SECONDS,
            15 * DateUtil.MINUTE_IN_SECONDS)
    // Define a unique tag for the task
    .setTag("test-upload")
    // ...finally, build the task and assign its value to myTask
    .build()
GcmNetworkManager.getInstance(this).schedule(myTask)

جاوا

// In GcmNetworkManager, this call defines the task and its
// runtime constraints:
OneoffTask myTask = new OneoffTask.Builder()
    // setService() says what class does the work
    .setService(MyUploadService.class)
    // Don't run the task unless device is charging
    .setRequiresCharging(true)
    // Run the task between 5 & 15 minutes from now
    .setExecutionWindow(
        5 * DateUtil.MINUTE_IN_SECONDS,
        15 * DateUtil.MINUTE_IN_SECONDS)
    // Define a unique tag for the task
    .setTag("test-upload")
    // ...finally, build the task and assign its value to myTask
    .build();
GcmNetworkManager.getInstance(this).schedule(myTask);

در این مثال، فرض می‌کنیم MyUploadService عملیات بارگذاری واقعی را تعریف می‌کند:

کاتلین

class MyUploadService : GcmTaskService() {
    fun onRunTask(params: TaskParams): Int {
        // Do some upload work
        return GcmNetworkManager.RESULT_SUCCESS
    }
}

جاوا

class MyUploadService extends GcmTaskService {
    @Override
    public int onRunTask(TaskParams params) {
        // Do some upload work
        return GcmNetworkManager.RESULT_SUCCESS;
    }
}

گنجاندن کتابخانه‌های WorkManager

برای استفاده از کلاس‌های WorkManager، باید کتابخانه WorkManager را به وابستگی‌های ساخت خود اضافه کنید. همچنین باید کتابخانه WorkManager GCM را اضافه کنید که به WorkManager امکان می‌دهد از GCM برای زمان‌بندی کار استفاده کند، وقتی برنامه‌تان در دستگاه‌هایی اجرا می‌شود که از JobScheduler پشتیبانی نمی‌کنند (یعنی دستگاه‌هایی که سطح API‏ ۲۲ یا پایین‌تر را اجرا می‌کنند). برای جزئیات کامل درباره افزودن کتابخانه‌ها، به شروع به کار با WorkManager مراجعه کنید.

اصلاح کردن مانیفست

وقتی GCMNetworkManager را پیاده‌سازی کردید، نمونه‌ای از GcmTaskService را به مانیفست برنامه‌تان اضافه کردید، همان‌طور که در GcmNetworkManager اسناد مرجع شرح داده شده است. GcmTaskService تکلیف ورودی را بررسی می‌کند و آن را به گرداننده تکلیف واگذار می‌کند. WorkManager واگذاری تکلیف به Worker را مدیریت می‌کند، بنابراین دیگر به کلاسی که این کار را انجام دهد نیاز ندارید؛ کافی است GcmTaskService را از مانیفست بردارید.

تعریف کردن Worker

پیاده‌سازی GCMNetworkManager شما OneoffTask یا RecurringTask را تعریف می‌کند، که مشخص می‌کند دقیقاً چه کاری باید انجام شود. باید آن را به‌صورت Worker بازنویسی کنید، همان‌طور که در تعریف درخواست‌های کار مستند شده است.

نمونه کد GCMNetworkManager یک تکلیف myTask را تعریف می‌کند. معادل WorkManager به‌صورت زیر است:

کاتلین

class UploadWorker(context: Context, params: WorkerParameters)
                        : Worker(context, params) {
    override fun doWork() : Result {
        // Do the upload operation ...
        myUploadOperation()

        // Indicate whether the task finished successfully with the Result
        return Result.success()
    }
}

جاوا

public class UploadWorker extends Worker {

    public UploadWorker(
        @NonNull Context context,
        @NonNull WorkerParameters params) {
        super(context, params);
    }

    @Override
    public Result doWork() {
      // Do the upload operation ...

      myUploadOperation()

      // Indicate whether the task finished successfully with the Result
      return Result.success()
    }
}

چند تفاوت بین تکلیف GCM و Worker وجود دارد:

  • ‫GCM از شیء TaskParams برای ارسال پارامترها به تکلیف استفاده می‌کند. WorkManager از داده‌های ورودی استفاده می‌کند که می‌توانید آن را در WorkRequest مشخص کنید، همان‌طور که در اسناد WorkManager برای تعریف ورودی/خروجی برای تکلیف شما شرح داده شده است. در هر دو مورد، می‌توانید جفت‌های کلید/مقدار را که هر پارامتر ماندگار موردنیاز تکلیف را مشخص می‌کند ارسال کنید.
  • GcmTaskService موفقیت یا شکست را با برگرداندن پرچم‌هایی مثل GcmNetworkManager.RESULT_SUCCESS نشان می‌دهد. یک WorkManager Worker نتایج خود را بااستفاده از یک روش ListenableWorker.Result، مانند ListenableWorker.Result.success()، و برگرداندن مقدار بازگشتی آن روش نشان می‌دهد.
  • همان‌طور که اشاره کردیم، هنگام تعریف کردن Worker، محدودیت‌ها یا برچسب‌ها را تنظیم نمی‌کنید؛ بلکه این کار را در مرحله بعد، هنگام ایجاد کردن WorkRequest انجام می‌دهید.

زمان‌بندی درخواست کار

تعریف کردن Worker مشخص می‌کند که چه کاری باید انجام شود. برای مشخص کردن اینکه کار چه زمانی باید انجام شود، باید WorkRequest را تعریف کنید:

  1. OneTimeWorkRequest یا PeriodicWorkRequest ایجاد کنید و هرگونه محدودیت دلخواه را که مشخص می‌کند تکلیف چه زمانی باید اجرا شود، و همچنین هرگونه برچسبی را برای شناسایی کارتان تنظیم کنید.
  2. درخواست را به WorkManager.enqueue() ارسال کنید تا تکلیف در صف اجرا قرار گیرد.

برای مثال، بخش قبلی نشان داد که چگونه یک OneoffTask را به یک Worker معادل تبدیل کنید. بااین‌حال، آن Worker شامل محدودیت‌های اجرا و برچسب شیء OneoffTask نبود. درعوض، هنگام ایجاد WorkRequest، محدودیت‌ها و شناسه تکلیف را تنظیم می‌کنیم. همچنین مشخص می‌کنیم که تکلیف نباید اجرا شود مگر اینکه اتصال شبکه وجود داشته باشد. نیازی نیست به‌طور صریح اتصال شبکه را با GCMNetworkManager درخواست کنید، زیرا GCMNetworkManager به‌طور پیش‌فرض به اتصال شبکه نیاز دارد، اما WorkManager به اتصال شبکه نیاز ندارد مگراینکه به‌طور خاص این محدودیت را اضافه کنید. وقتی WorkRequest را تعریف کردیم، آن را با WorkManager در صف قرار می‌دهیم.

کاتلین

val uploadConstraints = Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)
    .setRequiresCharging(true).build()

val uploadTask = OneTimeWorkRequestBuilder<UploadWorker>()
    .setConstraints(uploadConstraints)
    .build()
WorkManager.getInstance().enqueue(uploadTask)

جاوا

Constraints uploadConstraints = new Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)
    .setRequiresCharging(true)
    .build();

OneTimeWorkRequest uploadTask =
        new OneTimeWorkRequest.Builder(UploadWorker.class)
  .setConstraints(uploadConstraints)
  .build();
WorkManager.getInstance().enqueue(uploadTask);

نگاشت‌های میانای برنامه‌سازی کاربردی

این بخش توضیح می‌دهد که چگونه برخی‌از ویژگی‌ها و محدودیت‌های GCMNetworkManager با معادل‌های WorkManager مطابقت دارند.

نگاشت‌های محدودیت

GCMNetworkManager به شما امکان می‌دهد تعدادی محدودیت برای زمان اجرای تکلیف خود تنظیم کنید. در بیشتر موارد، یک محدودیت WorkManager معادل واضح وجود دارد. این بخش این معادل‌ها را فهرست می‌کند.

با فراخوانی روش مناسب در شیء Builder تکلیف، محدودیت‌هایی را برای تکالیف GCMNetworkManager تنظیم کنید؛ برای مثال، می‌توانید با فراخوانی Task.Builder.setRequiredNetwork()، الزامات شبکه را تنظیم کنید.

در WorkManager، یک شیء Constraints.Builder ایجاد می‌کنید و روش‌های آن شیء را برای تنظیم محدودیت‌ها (برای مثال، Constraints.Builder.setRequiredNetworkType())) فراخوانی می‌کنید، سپس از Builder برای ایجاد یک شیء Constraints استفاده می‌کنید که می‌توانید آن را به درخواست کار پیوست کنید. برای اطلاعات بیشتر، به تعریف درخواست‌های کاری مراجعه کنید.

محدودیت GCMNetworkManager معادل WorkManager یادداشت‌ها
setPersisted() (الزامی نیست) همه کارهای WorkManager در بازراه‌اندازی‌های دستگاه حفظ می‌شوند
setRequiredNetwork() setRequiredNetworkType() به‌طور پیش‌فرض، GCMNetworkManager به دسترسی به شبکه نیاز دارد. WorkManager به‌طور پیش‌فرض به دسترسی به شبکه نیاز ندارد. اگر کارتان به دسترسی به شبکه نیاز دارد، باید از setRequiredNetworkType(CONNECTED) استفاده کنید یا نوع شبکه خاص‌تری را تنظیم کنید.
setRequiresCharging()

نگاشت‌های دیگر

علاوه‌بر محدودیت‌ها، تنظیمات دیگری نیز وجود دارد که می‌توانید برای تکالیف GCMNetworkManager اعمال کنید. این بخش روش متناظر برای اعمال آن تنظیمات را در کار WorkManager فهرست می‌کند.

برچسب‌ها

همه تکالیف GCMNetworkManager باید رشته برچسب داشته باشند که با فراخوانی روش setTag() Builder تنظیم می‌کنید. کارهای WorkManager به‌طور منحصربه‌فرد با یک شناسه شناسایی می‌شوند که به‌طور خودکار توسط WorkManager تولید می‌شود؛ می‌توانید این شناسه را با فراخوانی WorkRequest.getId() دریافت کنید. علاوه‌براین، درخواست‌های کار می‌توانند به‌صورت اختیاری یک یا چند برچسب داشته باشند. برای تنظیم برچسب برای کار WorkManager، پیش‌از استفاده از آن Builder برای ایجاد WorkRequest، روش WorkRequest.Builder.addTag() را فراخوانی کنید.

در GCMNetworkManager، می‌توانید setUpdateCurrent() را فراخوانی کنید تا مشخص کنید آیا تکلیف باید جایگزین تکلیف موجود با همان برچسب شود یا نه. رویکرد WorkManager معادل این است که با فراخوانی enqueueUniqueWork() یا enqueueUniquePeriodicWork()، تکلیف را در صف قرار دهید؛ اگر از این روش‌ها استفاده کنید، نامی منحصربه‌فرد به کار می‌دهید و همچنین مشخص می‌کنید که اگر ازقبل کاری با آن نام در صف انتظار وجود داشته باشد، WorkManager چگونه باید درخواست را مدیریت کند. برای اطلاعات بیشتر، به مدیریت کارهای منحصربه‌فرد مراجعه کنید.

پارامترهای تکلیف

می‌توانید با فراخوانی Task.Builder.setExtras() و ارسال Bundle حاوی پارامترها، پارامترها را به کار GCMNetworkManager ارسال کنید. WorkManager به شما امکان می‌دهد شیء Data را به کار WorkManager ارسال کنید که حاوی پارامترها به‌صورت جفت‌های کلید/مقدار است. برای جزئیات، اختصاص دادن داده‌های ورودی را ببینید.