مهاجرت از 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 را قادر می‌سازد تا زمانی که برنامه شما روی دستگاه‌هایی اجرا می‌شود که JobScheduler را پشتیبانی نمی‌کنند (یعنی دستگاه‌هایی که API سطح 22 یا پایین‌تر دارند) از GCM برای زمان‌بندی کار استفاده کند. برای جزئیات کامل در مورد افزودن کتابخانه ها، شروع به کار با WorkManager را ببینید.

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

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

کارگر را تعریف کنید

پیاده سازی 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);
نقشه برداری API

این بخش نحوه نگاشت برخی از ویژگی ها و محدودیت های 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 باید دارای یک رشته برچسب باشند که با فراخوانی متد Builder'ssetTag setTag() تنظیم می کنید. مشاغل WorkManager به طور منحصر به فرد توسط یک شناسه شناسایی می شوند که به طور خودکار توسط WorkManager ایجاد می شود. می توانید با فراخوانی WorkRequest.getId() آن شناسه را دریافت کنید. علاوه بر این، درخواست های کاری می توانند به صورت اختیاری یک یا چند برچسب داشته باشند. برای تنظیم یک برچسب برای کار WorkManager خود، قبل از اینکه از آن Builder برای ایجاد WorkRequest استفاده کنید، متد WorkRequest.Builder.addTag() را فراخوانی کنید.

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

پارامترهای وظیفه

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