WorkManager হল Android-এ ব্যাকগ্রাউন্ডে স্থগিত করা যায় এমন কাজ শিডিউল ও এক্সিকিউট করার জন্য একটি লাইব্রেরি। Firebase JobDispatcher-এর পরিবর্তে এটি ব্যবহার করার সাজেশন দেওয়া হয়। নিম্নলিখিত গাইড আপনাকে Firebase JobDispatcher ইমপ্লিমেন্টেশন থেকে WorkManager-এ মাইগ্রেট করার প্রক্রিয়া সম্পর্কে জানাবে।
Gradle সেট-আপ
আপনার Android প্রোজেক্টে WorkManager লাইব্রেরি ইমপোর্ট করতে, WorkManager ব্যবহার শুরু করা-তে তালিকাভুক্ত ডিপেন্ডেন্সি যোগ করুন।
JobService থেকে কর্মীদের কাছে
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?" } }
জাভা
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। এছাড়াও,
Worker, RxWorker এবং CoroutineWorker (Kotlin coroutines
ব্যবহার করার সময়)-এর মতো
অন্যান্য উপযোগী সাবটাইপ রয়েছে।
JobService, ListenableWorker-এ ম্যাপ করে
আপনি সরাসরি JobService ব্যবহার করলে, এটি যে ওয়ার্কারের সাথে ম্যাপ করা আছে সেটি হল
ListenableWorker। আপনি SimpleJobService ব্যবহার করলে, এর পরিবর্তে
Worker ব্যবহার করা উচিত।
আসুন উপরের উদাহরণ (MyJobService) ব্যবহার করে দেখি যে কীভাবে আমরা এটিকে
ListenableWorker-এ পরিবর্তন করতে পারি।
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. } }
জাভা
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…() পদ্ধতিকে কল করা হয়েছে। OS কোনও কারণে আপনার কাজ বন্ধ করার সিদ্ধান্ত নিলে,
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") } }
জাভা
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. } }
এখানে doWork(), সিঙ্ক্রোনাসভাবে কাজ সম্পূর্ণ হওয়ার সিগন্যাল দিতে ListenableWorker.Result-এর একটি ইনস্ট্যান্স
ফেরত দেয়। এটি SimpleJobService-এর মতো, যা ব্যাকগ্রাউন্ড থ্রেডে
জব শিডিউল করে।
JobBuilder, WorkRequest-এ ম্যাপ করে
FirebaseJobBuilder Job মেটাডেটা দেখানোর জন্য Job.Builder ব্যবহার করে। WorkManager
এই ভূমিকা পালন করতে WorkRequest ব্যবহার করে।
WorkManager-এ দুই ধরনের WorkRequest আছে:
OneTimeWorkRequest এবং
PeriodicWorkRequest।
আপনি বর্তমানে Job.Builder.setRecurring(true) ব্যবহার করলে, আপনাকে
নতুন PeriodicWorkRequest তৈরি করতে হবে। অন্যথায়, আপনাকে
OneTimeWorkRequest ব্যবহার করতে হবে।
FirebaseJobDispatcher-এর সাহায্যে জটিল Job শিডিউল করা কেমন হতে পারে তা
দেখা যাক:
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)
জাভা
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-এর জন্য ইনপুট হিসেবে ব্যবহার করা যেতে পারে। FirebaseJobDispatcher-এর জন্য উপরে উল্লেখ করা ইনপুট ডেটা ও সীমাবদ্ধতার মতো একই ধরনের ডেটা ও সীমাবদ্ধতা ব্যবহার করেWorkRequestতৈরি করুন।WorkRequestকিউতে যোগ করুন।
Worker-এর জন্য ইনপুট সেট-আপ করা হচ্ছে
FirebaseJobDispatcher, JobService-এ ইনপুট ডেটা পাঠাতে Bundle ব্যবহার করে।
WorkManager এর পরিবর্তে Data ব্যবহার করে। তাহলে
এটি হবে:
Kotlin
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();
কর্মীর জন্য সীমাবদ্ধতা সেট-আপ করা হচ্ছে
FirebaseJobDispatcher
Job.Builder.setConstaints(...)
ব্যবহার করে চাকরির উপর সীমাবদ্ধতা সেট-আপ করে। WorkManager এর পরিবর্তে
Constraints ব্যবহার করে।
Kotlin
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();
WorkRequest (একবার বা পর্যায়ক্রমিক) তৈরি করা হচ্ছে
OneTimeWorkRequest এবং PeriodicWorkRequest তৈরি করতে আপনাকে
OneTimeWorkRequest.Builder
এবং PeriodicWorkRequest.Builder ব্যবহার করতে হবে।
উপরে উল্লেখ করা Job-এর মতো 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()
জাভা
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()
জাভা
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-এর সাথে সংজ্ঞায়িত প্রতিটি Job-এর একটি tag ছিল যা Job-কে
অনন্যভাবে শনাক্ত করতে ব্যবহার করা হয়েছিল। এছাড়াও, এটি অ্যাপ্লিকেশনকে শিডিউলারকে বলার একটি উপায় প্রদান করে
যদি Job-এর এই ইনস্ট্যান্সটি setReplaceCurrent কল করে
Job-এর একটি বিদ্যমান কপি প্রতিস্থাপন করতে হয়।
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()
জাভা
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() API ব্যবহার করে একই ফলাফল পেতে পারেন (যখন যথাক্রমে
OneTimeWorkRequest এবং PeriodicWorkRequest ব্যবহার করছেন)। আরও তথ্যের জন্য, WorkManager.enqueueUniqueWork()
এবং WorkManager.enqueueUniquePeriodicWork()-এর
রেফারেন্স পৃষ্ঠা দেখুন।
এটি দেখতে অনেকটা এইরকম হবে:
Kotlin
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);
কাজ বাতিল করা হচ্ছে
FirebaseJobDispatcher-এর মাধ্যমে আপনি এগুলি ব্যবহার করে কাজ বাতিল করতে পারবেন:
Kotlin
dispatcher.cancel("my-unique-tag")
জাভা
dispatcher.cancel("my-unique-tag");
WorkManager ব্যবহার করার সময় আপনি এগুলি ব্যবহার করতে পারবেন:
Kotlin
import androidx.work.WorkManager WorkManager.getInstance(myContext).cancelUniqueWork("my-unique-name")
জাভা
import androidx.work.WorkManager; WorkManager.getInstance(myContext).cancelUniqueWork("my-unique-name");
WorkManager শুরু করা হচ্ছে
WorkManager সাধারণত ContentProvider ব্যবহার করে নিজেকে ইনিশিয়ালাইজ করে।
WorkManager কীভাবে কাজ সাজায় এবং শিডিউল করে তার উপর আপনার আরও নিয়ন্ত্রণের প্রয়োজন হলে, আপনি WorkManager কনফিগারেশন এবং ইনিশিয়ালাইজেশন কাস্টমাইজ করতে পারেন।