Firebase JobDispatcher'dan WorkManager'a taşıma

WorkManager, ertelenebilir arka plan çalışmalarının planlanması ve yürütülmesi için kullanılan bir kitaplıktır bazı yolları da görmüştük. Firebase JobDispatcher için önerilen alternatiftir. İlgili içeriği oluşturmak için kullanılan Aşağıdaki rehber, Firebase'inizi taşıma sürecinde size yol gösterecektir WorkManager'a JobDispatcher uygulaması.

Gradle kurulumu

WorkManager kitaplığını Android projenize aktarmak için bağımlılıklarını WorkManager'ı kullanmaya başlama.

JobService'ten çalışanlara

FirebaseJobDispatcher şunun bir alt sınıfını kullanır: JobService yapılması gereken işleri tanımlamak için bir giriş noktası olarak kullanılmaktadır. En çok doğrudan JobService veya SimpleJobService

JobService aşağıdaki gibi görünür:

KotlinJava
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?"
    }
}
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 kullanıyorsanız onRunJob() politikasını geçersiz kılarsınız. @JobResult int türü döndürür.

Aradaki temel fark, JobService ürününü doğrudan (onStartJob()) kullanmanızdır. ana iş parçacığında çağrılır ve arka plandaki ileti dizisinde çalışır. Diğer yandan SimpleJobService, bu hizmet bir web sitesindeki çalışmanızı yürütmekten arka plan ileti dizisi.

WorkManager'da benzer kavramlar vardır. WorkManager'ın temel çalışma birimi ListenableWorker. Her biri 100'den az gösterim alan diğer yararlı alt türleri de vardır. Worker RxWorker ve CoroutineWorker ( kotlin eş yordamlarını kullanarak).

JobService, bir ListenableWorker ile eşlenir

Doğrudan JobService kullanıyorsanız eşlendiği çalışan bir ListenableWorker. SimpleJobService kullanıyorsanız Bunun yerine Worker.

Yukarıdaki örneği (MyJobService) kullanıp bunu nasıl dönüştürebileceğimize bakalım. ListenableWorker olarak değiştirdik.

KotlinJava
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.
    }
}
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'daki temel çalışma birimi ListenableWorker'dir. Aynı JobService.onStartJob(), startWork(), ana iş parçacığında çağrılıyor. Burası MyWorker, ListenableWorker öğesini uygular ve şunun bir örneğini döndürür: ListenableFuture, İşin tamamlanma durumunu eşzamansız olarak belirtmek için kullanılır. size özel bir ileti dizisi stratejisi oluşturduk.

Buradaki ListenableFuture, sonunda ListenableWorker.Result türünü döndürür. Bu değer Result.success(), Result.success(Data outputData), Result.retry(), Result.failure() veya Result.failure(Data outputData). Örneğin, daha fazla bilgi için referans sayfasına bakın; ListenableWorker.Result.

onStopped(), ListenableWorker öğesinin durması gerektiğini belirtmek için çağrılır, Bunun nedeni kısıtlamaların artık karşılanmamasıdır (örneğin, ağı artık kullanılamadığından) veya bir WorkManager.cancel…() yöntemi çağrıldı. onStopped(), işletim sistemi cihazınızı kapatmaya karar verirse bir sebepten ötürü zorlanmasıdır.

SimplejobService bir Çalışan ile eşlenir

SimpleJobService kullanılırken yukarıdaki çalışan aşağıdaki gibi görünür:

KotlinJava
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")
    }
}
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 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.
  }
}

Burada doWork(), işin sinyalini vermek için ListenableWorker.Result öğesinin bir örneğini döndürür eşzamanlı olarak tamamlayabilirsiniz. Bu, SimpleJobService programlarına benziyor. iş ilanlarına yazarlar.

JobBuilder, WorkRequest ile eşler

FirebasejobBuilder, Job meta verilerini göstermek için Job.Builder kullanır. İş Yöneticisi bu rolü doldurmak için WorkRequest kullanıyor.

WorkManager'da iki tür WorkRequest vardır: OneTimeWorkRequest ve PeriodicWorkRequest.

Şu anda Job.Builder.setRecurring(true) kullanıyorsanız yeni bir PeriodicWorkRequest oluşturun. Aksi takdirde OneTimeWorkRequest

FirebaseJobDispatcher için karmaşık bir Job planlamasının neden olabileceğine bakalım. gibi görünür:

KotlinJava
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)
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);

Bunu WorkManager ile yapmak için şunları yapmanız gerekir:

  • Worker için giriş olarak kullanılabilecek giriş verileri oluşturun.
  • Giriş verileri ve kısıtlamalara benzer kısıtlamalara sahip bir WorkRequest oluşturun yukarıda FirebaseJobDispatcher için tanımlanmıştır.
  • WorkRequest öğesini sıraya alın.

Çalışan için girişleri ayarlama

FirebaseJobDispatcher, giriş verilerini JobService cihazına göndermek için bir Bundle kullanır. WorkManager, bunun yerine Data kullanır. ODK şu hale gelir:

KotlinJava
import androidx.work.workDataOf
val data = workDataOf("some_key" to "some_val")
import androidx.work.Data;
Data input = new Data.Builder()
    .putString("some_key", "some_value")
    .build();

Çalışan İçin Kısıtlamaları Ayarlama

FirebaseJobDispatcher kullanımları Job.Builder.setConstaints(...) bu sayede işlerde kısıtlamalar oluşturabilirsiniz. WorkManager, Bunun yerine Constraints.

KotlinJava
import androidx.work.*

val constraints: Constraints = Constraints.Builder().apply {
    setRequiredNetworkType(NetworkType.CONNECTED)
    setRequiresCharging(true)
}.build()
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();

İş İsteği Oluşturma (Tek Seferlik veya Periyodik)

OneTimeWorkRequest ve PeriodicWorkRequest oluşturmak için OneTimeWorkRequest.Builder ve PeriodicWorkRequest.Builder.

Yukarıdakine benzer bir OneTimeWorkRequest oluşturmak için Job şunları yapın:

KotlinJava
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()
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();

Buradaki temel fark, WorkManager'ın işlerinin her zaman otomatik olarak yeniden başlatmasını sağlar.

PeriodicWorkRequest oluşturmak istiyorsanız aşağıdaki gibi bir işlem yapmanız gerekir:

KotlinJava
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()
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();

İşi planlama

Artık bir Worker ve WorkRequest tanımladığınıza göre, zaman çizelgesine uyacağınızı ifade etmelisiniz.

FirebaseJobDispatcher ile tanımlanan her Job, şu amaçla kullanılan bir tag içeriyordu: Job öğelerini benzersiz olarak tanımlayabilirsiniz. Ayrıca uygulamanın bu özelliği kullanarak Job örneğinin mevcut bir kopyasının yerine geçecekse planlayıcıya setReplaceCurrent numaralı telefonu arayarak Job.

KotlinJava
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()
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'ı kullanırken aynı sonucu enqueueUniqueWork() ve enqueueUniquePeriodicWork() API'leri ( sırasıyla OneTimeWorkRequest ve PeriodicWorkRequest). Daha fazla daha fazla bilgi için referans sayfalarına WorkManager.enqueueUniqueWork() ve WorkManager.enqueueUniquePeriodicWork().

Aşağıdaki gibi görünür:

KotlinJava
import androidx.work.*

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

OneTimeWorkRequest workRequest = // a WorkRequest;
WorkManager.getInstance(myContext)
    // 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);

İş iptal ediliyor

FirebaseJobDispatcher ile çalışmanızı iptal etmek için şunları kullanabilirsiniz:

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

WorkManager'ı kullanırken şunları kullanabilirsiniz:

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

WorkManager'ı başlatma

WorkManager genellikle bir ContentProvider kullanarak kendini başlatır. WorkManager'ın nasıl düzenlediği ve programladığı konusunda daha fazla kontrole ihtiyacınız varsa WorkManager yapılandırmasını ve başlatmayı özelleştirebilirsiniz.