WorkManager, Android'de ertelenebilir arka plan işlerini planlamak ve yürütmek için kullanılan bir kitaplıktır. Firebase JobDispatcher'ın yerine kullanılması önerilen çözümdür. Aşağıdaki kılavuz, Firebase JobDispatcher uygulamanızı WorkManager'a taşıma sürecinde size yol gösterecektir.
Gradle kurulumu
WorkManager kitaplığını Android projenize aktarmak için WorkManager'ı kullanmaya başlama bölümünde listelenen bağımlılıkları ekleyin.
JobService'ten çalışanlara
FirebaseJobDispatcher
, yapılması gereken işleri tanımlamak için giriş noktası olarak JobService
alt sınıfını kullanır. JobService
doğrudan veya SimpleJobService
kullanıyor olabilirsiniz.
JobService
öğesi şuna benzer:
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
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()
geçersiz kılınmış olur. Bu durumda @JobResult int
türü döndürülür.
Aralarındaki temel fark, JobService
özelliğini doğrudan kullanmanızdır. onStartJob()
, ana iş parçacığında çağrılır ve işi arka plan iş parçacığına yüklemek uygulamanın sorumluluğundadır. Diğer yandan, SimpleJobService
kullanıyorsanız bu hizmet, çalışmanızı bir arka plan iş parçacığı üzerinde yürütmekten sorumludur.
WorkManager benzer kavramlara sahiptir. WorkManager'daki temel çalışma birimi ListenableWorker
'dir. Worker
, RxWorker
ve CoroutineWorker
(Kotlin eş yordamlarını kullanırken) gibi başka kullanışlı çalışan alt türleri de vardır.
JobService, ListenableWorker ile eşlenir
Doğrudan JobService
kullanıyorsanız bu öğenin eşlendiği çalışan ListenableWorker
olmalıdır. SimpleJobService
kullanıyorsanız bunun yerine Worker
kullanmanız gerekir.
Yukarıdaki örneği (MyJobService
) kullanarak bunu nasıl ListenableWorker
biçimine dönüştürebileceğimize bakalım.
Kotlin
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'daki temel çalışma birimi ListenableWorker
'dir. JobService.onStartJob()
gibi, startWork()
de ana iş parçacığında çağrılır. Burada MyWorker
, ListenableWorker
işlemini uygular ve işin tamamlandığını eşzamansız olarak belirtmek için kullanılan bir ListenableFuture
örneğini döndürür. Kendi ileti dizisi stratejinizi
buradan seçmeniz gerekir.
Buradaki ListenableFuture
, sonunda Result.success()
, Result.success(Data outputData)
, Result.retry()
, Result.failure()
veya Result.failure(Data outputData)
olabilecek bir ListenableWorker.Result
türü döndürür. Daha fazla bilgi için ListenableWorker.Result
referans sayfasını inceleyin.
onStopped()
, kısıtlamaların artık karşılanmadığı (örneğin, ağ artık kullanılamadığı için) veya bir WorkManager.cancel…()
yöntemi çağrıldığı için ListenableWorker
durması gerektiğinin sinyalini vermek için çağrılır. İşletim sistemi herhangi bir nedenle çalışmanızı kapatmaya karar verirse onStopped()
de çağrılabilir.
SimpleJobService bir Worker ile eşlenir
SimpleJobService
kullanılırken yukarıdaki çalışan şöyle görünür:
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
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 tamamlandığını eşzamanlı olarak belirtmek için ListenableWorker.Result
örneğini döndürür. Bu, bir arka plan iş parçacığında işleri planlayan SimpleJobService
ile benzerdir.
JobBuilder, WorkRequest ile eşlenir
FirebaseJobBuilder, Job
meta verilerini temsil etmek için Job.Builder
kullanır. WorkManager, bu rolü doldurmak için WorkRequest
değerini kullanır.
WorkManager'da iki tür WorkRequest
bulunur:
OneTimeWorkRequest
ve
PeriodicWorkRequest
.
Şu anda Job.Builder.setRecurring(true)
kullanıyorsanız yeni bir PeriodicWorkRequest
oluşturmanız gerekir. Aksi takdirde OneTimeWorkRequest
kullanmanız gerekir.
FirebaseJobDispatcher
ile karmaşık bir Job
planlamasının nasıl olabileceğine bakalım:
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);
Aynı işlemi WorkManager'da yapabilmek için şunları yapmanız gerekir:
Worker
için giriş olarak kullanılabilecek giriş verileri oluşturun.- Giriş verileri ve yukarıda
FirebaseJobDispatcher
için tanımlanana benzer kısıtlamalarla birWorkRequest
oluşturun. WorkRequest
hattını 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. Böylece:
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();
Çalışan için Kısıtlamaları Ayarlama
FirebaseJobDispatcher
, işlerle ilgili kısıtlamalar ayarlamak için Job.Builder.setConstaints(...)
aracını kullanır. WorkManager bunun yerine Constraints
kullanır.
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'i Oluşturma (OneTime veya Periyodik)
OneTimeWorkRequest
ve PeriodicWorkRequest
oluşturmak için OneTimeWorkRequest.Builder
ve PeriodicWorkRequest.Builder
kullanmanız gerekir.
Yukarıdaki Job
öğesine benzer bir OneTimeWorkRequest
oluşturmak için aşağıdakileri yapmanız gerekir:
Kotlin
import androidx.work.* import java.util.concurrent.TimeUnit val constraints: Constraints = TODO("Define constraints as above") val request: 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();
Buradaki en önemli fark, WorkManager işlerinin cihazı yeniden başlatma işleminde her zaman devamlı olmasıdır.
PeriodicWorkRequest
oluşturmak istiyorsanız aşağıdaki gibi bir işlem yapmanız gerekir:
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();
İşleri programlama
Worker
ve WorkRequest
tanımladığınıza göre, artık bir çalışma planlamaya hazırsınız.
FirebaseJobDispatcher
ile tanımlanan her Job
, bir Job
'i benzersiz bir şekilde tanımlamak için kullanılan bir tag
içeriyordu. Ayrıca, uygulamanın bu Job
örneğinin setReplaceCurrent
yöntemini çağırarak mevcut Job
kopyasıyla değiştirilip değiştirilmeyeceğini de planlayıcıya bildirmesi için bir yol sağladı.
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 kullanırken enqueueUniqueWork()
ve enqueueUniquePeriodicWork()
API'lerini kullanarak aynı sonucu elde edebilirsiniz (sırasıyla OneTimeWorkRequest
ve PeriodicWorkRequest
kullanırken). Daha fazla bilgi için WorkManager.enqueueUniqueWork()
ve WorkManager.enqueueUniquePeriodicWork()
referans sayfalarını inceleyin.
Bu, aşağıdaki gibi bir şeydir:
Kotlin
import androidx.work.* val request: "A WorkRequest") WorkManager.getInstance(myContext) .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(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ışmayı iptal etmek için şunları kullanabilirsiniz:
Kotlin
dispatcher.cancel("my-unique-tag")
Java
dispatcher.cancel("my-unique-tag");
WorkManager'ı kullanırken şunları kullanabilirsiniz:
Kotlin
import androidx.work.WorkManager WorkManager.getInstance(myContext).cancelUniqueWork("my-unique-name")
Java
import androidx.work.WorkManager; WorkManager.getInstance(myContext).cancelUniqueWork("my-unique-name");
WorkManager başlatılıyor
WorkManager genellikle bir ContentProvider
kullanarak kendini başlatır.
WorkManager'ın düzenleme ve programlama çalışma şekli üzerinde daha fazla kontrole ihtiyacınız varsa WorkManager yapılandırmasını ve başlatmayı özelleştirebilirsiniz.