الترحيل من Firebase JobDispatcher

الإعلانات

الترحيل من Firebase JobDispatcher إلى WorkManager

WorkManager هي مكتبة لجدولة وتنفيذ، الأعمال الخلفية المحتمله في أندرويد. وهي الإستبدال الموصى به لـ FireBase JobDispatcher.

سيرشدك الدليل التالي، خلال عملية الترحيل من FireBase JobDispatcher إلى WorkManager.

إعداد ملف البناء Gradle


ملاحظة: تتمثل الخطوة الأولى في الترحيل من Firebase JobDispatcher في تضمين أحدث إعتمادات البناء في WorkManager.

لإستيراد WorkManager إلى مشروع الأندرويد، راجع الإرشادات الخاصة بالإعلان عن الإعتمادات في ملاحظات إصدار WorkManager.

 

 

من JobService إلى Workers


تستخدم FirebaseJobDispatcher فئة فرعية من JobService كنقطة دخول، لتحديد العمل الذي يجب إنجازه.

قد تستخدم JobService مباشرة، أو تستخدم SimpleJobService.

ستبدو JobService كالتالي:

KOTLIN
import com.firebase.jobdispatcher.JobParameters
import com.firebase.jobdispatcher.JobService

class MyJobService : JobService() {
    override fun onStartJob(job: JobParameters): Boolean {
        // Do some work here
        return false // Answers the question: "Is there still work going on?"
    }
    override fun onStopJob(job: JobParameters): Boolean {
        return false // Answers the question: "Should this job be retried?"
    }
}

 

JAVA الترحيل من Firebase JobDispatcher إلى WorkManager
import com.firebase.jobdispatcher.JobParameters;
import com.firebase.jobdispatcher.JobService;

public class MyJobService extends JobService {
    @Override
    public boolean onStartJob(JobParameters job) {
        // Do some work here

        return false; // Answers the question: "Is there still work going on?"
    }

    @Override
    public boolean onStopJob(JobParameters job) {
        return false; // Answers the question: "Should this job be retried?"
    }
}

 

إذا كنت تستخدم SimpleJobService ، فسوف يتوجب عليك تجاوز ()onRunJob ، التي تقوم بإرجاع نوع JobResult int@.

الفرق الرئيسي هو، عندما تقوم بإستخدام JobService مباشرة، يتم إستدعاء ()onStartJob على مؤشر الترابط الرئيسي، ومن مسؤولية التطبيق..

نقل العمل إلى مؤشر الترابط الخلفي. من ناحية أخرى، إذا كنت تستخدم SimpleJobService، فإن هذه الخدمة مسؤولة عن، تنفيذ عملك على مؤشر الترابط الخلفي.

WorkManager لديه مفاهيم مماثلة. الوحدة الأساسية للعمل في WorkManager هي ListenableWorker.

هناك أيضاً أنواع فرعية أخرى مفيدة، من workers مثل Worker و RxWorker و CoroutineWorker (عند إستخدام الأمور الإعتياديه لكوتلن).

 

 

توصيل JobService بـ ListenableWorker

 

 

إذا كنت تستخدم JobService مباشرة، فإن العامل الذي يقوم بتوصيلها هو ListenableWorker.

إذا كنت تستخدم SimpleJobService فيجب عليك إستخدام العامل بدلاً من ذلك.

دعونا نستخدم المثال أعلاه (MyJobService) وننظر في كيفية قيامنا بتحويله إلى ListenableWorker.

KOTLIN الترحيل من Firebase JobDispatcher إلى WorkManager

import android.content.Context
import androidx.work.ListenableWorker
import androidx.work.ListenableWorker.Result
import androidx.work.WorkerParameters
import com.google.common.util.concurrent.ListenableFuture

class MyWorker(appContext: Context, params: WorkerParameters) :
    ListenableWorker(appContext, params) {

    override fun startWork(): ListenableFuture<ListenableWorker.Result> {
        // Do your work here.
        TODO("Return a ListenableFuture<Result>")
    }

    override fun onStopped() {
        // Cleanup because you are being stopped.
    }
}

 

JAVA

import android.content.Context;
import androidx.work.ListenableWorker;
import androidx.work.ListenableWorker.Result;
import androidx.work.WorkerParameters;
import com.google.common.util.concurrent.ListenableFuture;

class MyWorker extends ListenableWorker {

  public MyWorker(@NonNull Context appContext, @NonNull WorkerParameters params) {
    super(appContext, params);
  }

  @Override
  public ListenableFuture<ListenableWorker.Result> startWork() {
    // Do your work here.
    Data input = getInputData();

    // Return a ListenableFuture<>
  }

  @Override
  public void onStopped() {
    // Cleanup because you are being stopped.
  }
}

 

 

الوحدة الأساسية للعمل في WorkManager هي ListenableWorker. تماماً مثل ()JobService.onStartJob

يتم إستدعاء ()startWork على مؤشر الترابط الرئيسي. هنا MyWorker يقوم بتنفيذ ListenableWorker ثم إرجاع مثيل من ListenableFuture ،..

والذي يستخدم للإشارة إلى إنجاز العمل، بشكلٍ غير متزامن. يجب عليك إختيار إستراتيجية مؤشر الترابط الخاصة بك هنا.

في نهاية المطاف تقوم ListenableFuture هنا، بإرجاع نوع ListenableWorker.Result التي يمكن أن تكون واحدة من
()Result.success
 (Result.success (Data  outputData
 ()Result.retry
()Result.failure
أو (Result.failure (data outputData

لمزيد من المعلومات، يرجى الإطلاع على الصفحة المرجعية لـ ListenableWorker.Result.

يتم إستدعاء ()onStopped للإشارة إلى أن ListenableWorker يحتاج إلى إيقاف، إما بسبب عدم الإستجابة للقيود (على سبيل المثال، بسبب عدم توفر الشبكة)..

أو بسبب إستدعاء دالة ()...WorkManager.cancel . قد يتم إستدعاء ()onStopped أيضاً، إذا قرر نظام التشغيل، إيقاف عملك لسببٍ ما.

 

 

توصيل SimpleJobService بـ Worker

عند إستخدام SimpleJobService فإن العامل المذكور أعلاه سيبدو كالتالي:

KOTLIN

import android.content.Context;
import androidx.work.Data;
import androidx.work.ListenableWorker.Result;
import androidx.work.Worker;
import androidx.work.WorkerParameters;


class MyWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
    override fun doWork(): Result {
        TODO("Return a Result")
    }

    override fun onStopped() {
        super.onStopped()
        TODO("Cleanup, because you are being stopped")
    }
}

 

JAVA الترحيل من Firebase JobDispatcher إلى WorkManager

import android.content.Context;
import androidx.work.Data;
import androidx.work.ListenableWorker.Result;
import androidx.work.Worker;
import androidx.work.WorkerParameters;

class MyWorker extends Worker {

  public MyWorker(@NonNull Context appContext, @NonNull WorkerParameters params) {
    super(appContext, params);
  }

  @Override
  public ListenableWorker.Result doWork() {
    // Do your work here.
    Data input = getInputData();

    // Return a ListenableWorker.Result
    Data outputData = new Data.Builder()
        .putString(“Key”, “value”)
        .build();
    return Result.success(outputData);
  }

  @Override
  public void onStopped() {
    // Cleanup because you are being stopped.
  }
}

 

 

هنا تقوم دالة ()doWork بإرجاع مثيل من ListenableWorker.Result للإشارة إلى إنجاز العمل بشكلٍ متزامن.

وهذا مشابه لـ SimpleJobService التي تقوم بجدولة العمل على مؤشر الترابط الخلفي.

 

 

توصيل JobBuilder بـ WorkRequests


 

FirebaseJobBuilder تستخدم Job.Builder لتمثيل البيانات الوصفية للعمل.
WorkManager يستخدم WorkRequest لملء هذه الوظيفه.

لدى WorkManager نوعين من WorkRequests:
OneTimeWorkRequest و PeriodicWorkRequest.

إذا كنت حالياً تستخدم (Job.Builder.setRecurring(true، فيجب عليك إنشاء PeriodicWorkRequest جديد.

وإلا فإنه يجب عليك إستخدام OneTimeWorkRequest.

لنلقي نظرة على ما يقوم بجدولة مهمة معقده بإستخدام FirebaseJobDispatcher والتي قد تبدو كما يلي:

KOTLIN

val input:Bundle = Bundle().apply {
    putString("some_key", "some_value")
}

val job = dispatcher.newJobBuilder()
    // the JobService that will be called
    .setService(MyService::class.java)
    // uniquely identifies the job
    .setTag("my-unique-tag")
    // one-off job
    .setRecurring(false)
    // don't persist past a device reboot
    .setLifetime(Lifetime.UNTIL_NEXT_BOOT)
    // start between 0 and 60 seconds from now
    .setTrigger(Trigger.executionWindow(0, 60))
    // don't overwrite an existing job with the same tag
    .setReplaceCurrent(false)
    // retry with exponential backoff
    .setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL)

    .setConstraints(
        // only run on an unmetered network
        Constraint.ON_UNMETERED_NETWORK,
        // // only run when the device is charging
        Constraint.DEVICE_CHARGING
    )
    .setExtras(input)
    .build()

dispatcher.mustSchedule(job)

 

JAVA

Bundle input = new Bundle();
input.putString("some_key", "some_value");

Job myJob = dispatcher.newJobBuilder()
    // the JobService that will be called
    .setService(MyJobService.class)
    // uniquely identifies the job
    .setTag("my-unique-tag")
    // one-off job
    .setRecurring(false)
    // don't persist past a device reboot
    .setLifetime(Lifetime.UNTIL_NEXT_BOOT)
    // start between 0 and 60 seconds from now
    .setTrigger(Trigger.executionWindow(0, 60))
    // don't overwrite an existing job with the same tag
    .setReplaceCurrent(false)
    // retry with exponential backoff
    .setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL)
    // constraints that need to be satisfied for the job to run
    .setConstraints(
        // only run on an unmetered network
        Constraint.ON_UNMETERED_NETWORK,
        // only run when the device is charging
        Constraint.DEVICE_CHARGING
    )
    .setExtras(input)
    .build();

dispatcher.mustSchedule(myJob);

 

 

لتحقيق نفس الأمر إثناء إستخدام WorkManager سوف تحتاج إلى:

  • بناء بيانات الإدخال والتي يمكن إستخدامها كمدخل للعامل Worker.
  •  بناء WorkRequest بإستخدام بيانات الإدخال و القيود، المشابهة لتلك التي تم تعريفها أعلاه لـ FirebaseJobDispatcher.
  •  قائمة إنتظار WorkRequest.

 

 

إعداد المدخلات لـWorker

FirebaseJobDispatcher تستخدم حزمة، لإرسال البيانات المدخله، إلى JobService.

WorkManager تستخدم البيانات بدلاً من ذلك. بحيث يصبح ذلك:

KOTLIN

import androidx.work.workDataOf
val data = workDataOf("some_key" to "some_val")

 

JAVA

import androidx.work.Data;
Data input = new Data.Builder()
    .putString("some_key", "some_value")
    .build();

 

 

 

إعداد القيود لـWorker

 

FirebaseJobDispatcher تستخدم (...)Job.Builder.setConstaints لإعداد قيود على الوظائف.

WorkManager تستخدم القيود بدلاً من ذلك.

KOTLIN
import androidx.work.*

val constraints: Constraints = Constraints.Builder().apply {
    setRequiredNetworkType(NetworkType.CONNECTED)
    setRequiresCharging(true)
}.build()

 

JAVA
import androidx.work.Constraints;
import androidx.work.Constraints.Builder;
import androidx.work.NetworkType;

Constraints constraints = new Constraints.Builder()
    // The Worker needs Network connectivity
    .setRequiredNetworkType(NetworkType.CONNECTED)
    // Needs the device to be charging
    .setRequiresCharging(true)
    .build();

 

 

إنشاء WorkRequest (مرة واحدة أو بشكلٍ دوري)

 

لإنشاء OneTimeWorkRequests و PeriodicWorkRequests يجب عليك إستخدام OneTimeWorkRequest.Builder و PeriodicWorkRequest.Builder.

لإنشاء OneTimeWorkRequest والذي هو مشابه للوظيفة أعلاه، يجب عليك فعل التالي:

KOTLIN

import androidx.work.*
import java.util.concurrent.TimeUnit

val constraints: Constraints = TODO("Define constraints as above")
val request: OneTimeWorkRequest =
     // Tell which work to execute
     OneTimeWorkRequestBuilder<MyWorker>()
         // Sets the input data for the ListenableWorker
        .setInputData(input)
        // If you want to delay the start of work by 60 seconds
        .setInitialDelay(60, TimeUnit.SECONDS)
        // Set a backoff criteria to be used when retry-ing
        .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 30000, TimeUnit.MILLISECONDS)
        // Set additional constraints
        .setConstraints(constraints)
        .build()

 

JAVA

import androidx.work.BackoffCriteria;
import androidx.work.Constraints;
import androidx.work.Constraints.Builder;
import androidx.work.NetworkType;
import androidx.work.OneTimeWorkRequest;
import androidx.work.OneTimeWorkRequest.Builder;
import androidx.work.Data;

// Define constraints (as above)
Constraints constraints = ...
OneTimeWorkRequest request =
    // Tell which work to execute
    new OneTimeWorkRequest.Builder(MyWorker.class)
        // Sets the input data for the ListenableWorker
        .setInputData(inputData)
        // If you want to delay the start of work by 60 seconds
        .setInitialDelay(60, TimeUnit.SECONDS)
        // Set a backoff criteria to be used when retry-ing
        .setBackoffCriteria(BackoffCriteria.EXPONENTIAL, 30000, TimeUnit.MILLISECONDS)
        // Set additional constraints
        .setConstraints(constraints)
        .build();

 

الإختلاف الرئيسي هنا هو، أن وظائف WorkManager دائماً ما تكون مستمرة إثناء إعادة تشغيل الجهاز تلقائياً.

إذا كنت تريد إنشاء PeriodicWorkRequest (دوري) فيجب عليك فعل شيء مثل:

KOTLIN

val constraints: Constraints = TODO("Define constraints as above")
val request: PeriodicWorkRequest =
PeriodicWorkRequestBuilder<MyWorker>(15, TimeUnit.MINUTES)
    // Sets the input data for the ListenableWorker
    .setInputData(input)
    // Other setters
    .build()

 

JAVA

import androidx.work.BackoffCriteria;
import androidx.work.Constraints;
import androidx.work.Constraints.Builder;
import androidx.work.NetworkType;
import androidx.work.PeriodicWorkRequest;
import androidx.work.PeriodicWorkRequest.Builder;
import androidx.work.Data;

// Define constraints (as above)
Constraints constraints = ...

PeriodicWorkRequest request =
    // Executes MyWorker every 15 minutes
    new PeriodicWorkRequest.Builder(MyWorker.class, 15, TimeUnit.MINUTES)
        // Sets the input data for the ListenableWorker
        .setInputData(input)
        . // other setters (as above)
        .build();

 

 

جدولة العمل


الآن بعد أن قمت بتحديد Worker و WorkRequest، أصبحت جاهزاً لجدولة العمل.

كل وظيفة تم تعريفها بإستخدام FirebaseJobDispatcher لديها وسم إستخدم لتعريف الوظيفة بشكلٍ فريد.

كما أنه يوفر طريقة أيضاً للتطبيق، ليخبر الجدوله إذا ما كان مثيل الوظيفة هذا، كان ليقوم بإستبدال نسخة حاليه من الوظيفة من خلال إستدعاء setReplaceCurrent.

KOTLIN

val job = dispatcher.newJobBuilder()
    // the JobService that will be called
    .setService(MyService::class.java)
    // uniquely identifies the job
    .setTag("my-unique-tag")
    // don't overwrite an existing job with the same tag
    .setRecurring(false)
    // Other setters...
    .build()

 

JAVA

Job myJob = dispatcher.newJobBuilder()
    // the JobService that will be called
    .setService(MyJobService.class)
    // uniquely identifies the job
    .setTag("my-unique-tag")
    // don't overwrite an existing job with the same tag
    .setReplaceCurrent(false)
    // other setters
    // ...

dispatcher.mustSchedule(myJob);

 

عند إستخدام WorkManager، يمكنك تحقيق نفس النتيجة من خلال إستخدام واجهات برمجة تطبيقات ()enqueueUniqueWork و ()enqueueUniquePeriodicWork ..

(عند إستخدام OneTimeWorkRequest و PeriodicWorkRequest على التوالي).

لمزيد من المعلومات، راجع الصفحات المرجعية لـ ()WorkManager.enqueueUniqueWork و ()WorkManager.enqueueUniquePeriodicWork.

سيبدو هذا كما يلي:

KOTLIN

import androidx.work.*

val request: OneTimeWorkRequest = TODO("A WorkRequest")
WorkManager.getInstance()
    .enqueueUniqueWork("my-unique-name", ExistingWorkPolicy.KEEP, request)

 

JAVA

import androidx.work.ExistingWorkPolicy;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;

OneTimeWorkRequest workRequest = // a WorkRequest;
WorkManager.getInstance()
    // Use ExistingWorkPolicy.REPLACE to cancel and delete any existing pending
    // (uncompleted) work with the same unique name. Then, insert the newly-specified
    // work.
    .enqueueUniqueWork("my-unique-name", ExistingWorkPolicy.KEEP, workRequest);

 

 

ملاحظة: وسوم الوظيفة تقوم بتوصيل FirebaseJobDispatcher إلى أسماء WorkRequests الخاصة بـ WorkManager.

 

 

إلغاء العمل


بإستخدام FirebaseJobDispatcher، يمكنك إلغاء العمل بإستخدام:

KOTLIN

dispatcher.cancel("my-unique-tag")

 

JAVA

dispatcher.cancel("my-unique-tag");

 

عند إستخدام WorkManager يمكنك إستخدام:

KOTLIN

import androidx.work.WorkManager
WorkManager.getInstance().cancelUniqueWork("my-unique-name")

 

JAVA

 

 

تهيئة WorkManager


WorkManager يحتاج إلى التهيئة مرة واحدة لكل تطبيق، يكون ذلك عادة بإستخدام ContentProvider أو ()Application.onCreate.

WorkManager عادة ما يقوم بتهيئة نفسه بإستخدام ContentProvider. مع ذلك، هناك بعض الإختلافات الطفيفه في..

الإعدادات الإفتراضيه فيما يتعلق بحجم مجموعة مؤشرات الترابط threadpool، و عدد workers التي يمكن جدولتها في وقت محدد.

لذا قد تحتاج إلى تخصيص WorkManager.

عادة، يتم إجراء هذا التخصيص بإستخدام ()WorkManager.initialize.

وهذا يسمح لك بتخصيص المنفذ الخلفي، المستخدم لتشغيل Workers، و WorkerFactory تستخدم لإنشاء Workers.

(WorkerFactory مفيد في سياق إدخال (حقن) الإعتمادات). يرجى قراءة الوثائق الخاصة بهذه الداله للتأكد من إيقافك للتهيئة التلقائية لـWorkManager.

لمزيد من المعلومات، راجع الوثائق الخاصة بـ ()initialize و Configuration.Builder.

 

 


للإطلاع على المقال باللغة الإنجليزية أضغط هنا.

الإعلانات

اترك رد