কাজ পরিচালনা

একবার আপনি আপনার Worker এবং আপনার WorkRequest সংজ্ঞায়িত করলে, শেষ ধাপ হল আপনার কাজ সারিবদ্ধ করা। কাজ সারিবদ্ধ করার সবচেয়ে সহজ উপায় হল WorkManager enqueue() পদ্ধতিতে কল করা, আপনি যে WorkRequest চালাতে চান তা পাস করে।

কোটলিন

val myWork: WorkRequest = // ... OneTime or PeriodicWork
WorkManager.getInstance(requireContext()).enqueue(myWork)

জাভা

WorkRequest myWork = // ... OneTime or PeriodicWork
WorkManager.getInstance(requireContext()).enqueue(myWork);

ডুপ্লিকেশন এড়াতে কাজের সারিবদ্ধ করার সময় সতর্কতা অবলম্বন করুন। উদাহরণস্বরূপ, একটি অ্যাপ প্রতি 24 ঘন্টায় একটি ব্যাকএন্ড পরিষেবাতে তার লগগুলি আপলোড করার চেষ্টা করতে পারে। আপনি যদি সতর্ক না হন তবে আপনি একই কাজটি অনেকবার সারিবদ্ধ করতে পারেন, যদিও কাজটি শুধুমাত্র একবার চালানোর প্রয়োজন হয়। এই লক্ষ্য অর্জনের জন্য, আপনি কাজটিকে অনন্য কাজ হিসাবে নির্ধারণ করতে পারেন।

অনন্য কাজ

অনন্য কাজ হল একটি শক্তিশালী ধারণা যা গ্যারান্টি দেয় যে আপনার কাছে একবারে একটি নির্দিষ্ট নামের সাথে কাজ করার একটি উদাহরণ রয়েছে। আইডিগুলির বিপরীতে, অনন্য নামগুলি মানব-পাঠযোগ্য এবং WorkManager দ্বারা স্বয়ংক্রিয়ভাবে তৈরি হওয়ার পরিবর্তে বিকাশকারী দ্বারা নির্দিষ্ট করা হয়৷ ট্যাগের বিপরীতে, অনন্য নাম শুধুমাত্র কাজের একটি একক উদাহরণের সাথে যুক্ত।

স্বতন্ত্র কাজ এককালীন এবং পর্যায়ক্রমিক উভয় কাজেই প্রয়োগ করা যেতে পারে। আপনি এই পদ্ধতিগুলির একটিতে কল করে একটি অনন্য কাজের ক্রম তৈরি করতে পারেন, আপনি পুনরাবৃত্তিমূলক কাজ বা এককালীন কাজের সময় নির্ধারণ করছেন কিনা তার উপর নির্ভর করে।

এই উভয় পদ্ধতি 3টি আর্গুমেন্ট গ্রহণ করে:

  • uniqueWorkName - কাজের অনুরোধকে স্বতন্ত্রভাবে সনাক্ত করতে ব্যবহৃত একটি String
  • existingWorkPolicy - একটি enum যা ওয়ার্ক ম্যানেজারকে বলে যে সেই অনন্য নামের সাথে ইতিমধ্যেই একটি অসমাপ্ত কাজের চেইন থাকলে কি করতে হবে৷ আরও তথ্যের জন্য দ্বন্দ্ব সমাধান নীতি দেখুন।
  • work - নির্ধারিত WorkRequest

অনন্য কাজ ব্যবহার করে, আমরা আগে উল্লেখ করা আমাদের ডুপ্লিকেট সময়সূচী সমস্যা সমাধান করতে পারি।

কোটলিন

val sendLogsWorkRequest =
       PeriodicWorkRequestBuilder<SendLogsWorker>(24, TimeUnit.HOURS)
           .setConstraints(Constraints.Builder()
               .setRequiresCharging(true)
               .build()
            )
           .build()
WorkManager.getInstance(this).enqueueUniquePeriodicWork(
           "sendLogs",
           ExistingPeriodicWorkPolicy.KEEP,
           sendLogsWorkRequest
)

জাভা

PeriodicWorkRequest sendLogsWorkRequest = new
      PeriodicWorkRequest.Builder(SendLogsWorker.class, 24, TimeUnit.HOURS)
              .setConstraints(new Constraints.Builder()
              .setRequiresCharging(true)
          .build()
      )
     .build();
WorkManager.getInstance(this).enqueueUniquePeriodicWork(
     "sendLogs",
     ExistingPeriodicWorkPolicy.KEEP,
     sendLogsWorkRequest);

এখন, যদি একটি sendLogs কাজ ইতিমধ্যেই সারিতে থাকা অবস্থায় কোডটি চলে, তাহলে বিদ্যমান কাজটি রাখা হয় এবং কোনো নতুন কাজ যোগ করা হয় না।

আপনার যদি ধীরে ধীরে কাজের একটি দীর্ঘ চেইন তৈরি করতে হয় তবে অনন্য কাজের ক্রমগুলিও কার্যকর হতে পারে। উদাহরণস্বরূপ, একটি ফটো এডিটিং অ্যাপ ব্যবহারকারীদের কর্মের একটি দীর্ঘ শৃঙ্খল পূর্বাবস্থায় ফেরাতে দিতে পারে। এই পূর্বাবস্থার প্রতিটি ক্রিয়াকলাপ কিছুটা সময় নিতে পারে, তবে সেগুলি সঠিক ক্রমে সম্পাদন করতে হবে। এই ক্ষেত্রে, অ্যাপটি একটি "আনডু" চেইন তৈরি করতে পারে এবং প্রয়োজন অনুযায়ী প্রতিটি পূর্বাবস্থার ক্রিয়াকলাপ চেইনে যুক্ত করতে পারে। আরও বিস্তারিত জানার জন্য চেইনিং কাজ দেখুন।

দ্বন্দ্ব সমাধান নীতি

অনন্য কাজের সময়সূচী করার সময়, আপনাকে অবশ্যই ওয়ার্ক ম্যানেজারকে বলতে হবে যখন কোন দ্বন্দ্ব দেখা দেয় তখন কি পদক্ষেপ নিতে হবে। কাজ সারিবদ্ধ করার সময় আপনি একটি enum পাস করে এটি করবেন।

এককালীন কাজের জন্য, আপনি একটি ExistingWorkPolicy প্রদান করেন, যা দ্বন্দ্ব পরিচালনার জন্য 4টি বিকল্প সমর্থন করে।

  • নতুন কাজের সাথে বিদ্যমান কাজ REPLACE । এই বিকল্পটি বিদ্যমান কাজ বাতিল করে।
  • বিদ্যমান কাজ KEEP এবং নতুন কাজ উপেক্ষা করুন।
  • বিদ্যমান কাজ শেষ করে নতুন কাজ APPEND । এই নীতিটি আপনার নতুন কাজকে বিদ্যমান কাজের সাথে শৃঙ্খলিত করবে, বিদ্যমান কাজ শেষ হওয়ার পরে চলবে।

বিদ্যমান কাজ নতুন কাজের পূর্বশর্ত হয়ে ওঠে। বিদ্যমান কাজটি CANCELLED বা FAILED হলে, নতুন কাজটিও CANCELLED বা FAILED হয়। আপনি যদি চান যে বিদ্যমান কাজের স্থিতি নির্বিশেষে নতুন কাজ চলুক, তবে পরিবর্তে APPEND_OR_REPLACE ব্যবহার করুন৷

  • APPEND_OR_REPLACE ফাংশন APPEND এর মতোই, ব্যতীত এটি পূর্বশর্ত কাজের অবস্থার উপর নির্ভরশীল নয়। যদি বিদ্যমান কাজ CANCELLED বা FAILED হয়, নতুন কাজ এখনও চলে।

পিরিয়ড কাজের জন্য, আপনি একটি ExistingPeriodicWorkPolicy প্রদান করেন, যা 2টি বিকল্প, REPLACE এবং KEEP সমর্থন করে। এই বিকল্পগুলি তাদের ExistingWorkPolicy প্রতিপক্ষের মতই কাজ করে।

আপনার কাজ পর্যবেক্ষণ

কাজ সারিবদ্ধ করার পরে যে কোনো সময়ে, আপনি WorkManager এর name , id বা এর সাথে যুক্ত একটি tag দ্বারা অনুসন্ধান করে এর স্থিতি পরীক্ষা করতে পারেন।

কোটলিন

// by id
workManager.getWorkInfoById(syncWorker.id) // ListenableFuture<WorkInfo>

// by name
workManager.getWorkInfosForUniqueWork("sync") // ListenableFuture<List<WorkInfo>>

// by tag
workManager.getWorkInfosByTag("syncTag") // ListenableFuture<List<WorkInfo>>

জাভা

// by id
workManager.getWorkInfoById(syncWorker.id); // ListenableFuture<WorkInfo>

// by name
workManager.getWorkInfosForUniqueWork("sync"); // ListenableFuture<List<WorkInfo>>

// by tag
workManager.getWorkInfosByTag("syncTag"); // ListenableFuture<List<WorkInfo>>

কোয়েরিটি একটি WorkInfo অবজেক্টের একটি ListenableFuture প্রদান করে, যার মধ্যে কাজের id , এর ট্যাগ, এর বর্তমান State এবং Result.success(outputData) এর মাধ্যমে সেট করা যেকোনো আউটপুট ডেটা অন্তর্ভুক্ত থাকে।

প্রতিটি পদ্ধতির একটি LiveData ভেরিয়েন্ট আপনাকে একজন শ্রোতা নিবন্ধন করে WorkInfo তে পরিবর্তনগুলি পর্যবেক্ষণ করতে দেয়। উদাহরণস্বরূপ, কিছু কাজ সফলভাবে শেষ হলে আপনি যদি ব্যবহারকারীর কাছে একটি বার্তা প্রদর্শন করতে চান তবে আপনি এটি নিম্নরূপ সেট আপ করতে পারেন:

কোটলিন

workManager.getWorkInfoByIdLiveData(syncWorker.id)
               .observe(viewLifecycleOwner) { workInfo ->
   if(workInfo?.state == WorkInfo.State.SUCCEEDED) {
       Snackbar.make(requireView(), 
      R.string.work_completed, Snackbar.LENGTH_SHORT)
           .show()
   }
}

জাভা

workManager.getWorkInfoByIdLiveData(syncWorker.id)
        .observe(getViewLifecycleOwner(), workInfo -> {
    if (workInfo.getState() != null &&
            workInfo.getState() == WorkInfo.State.SUCCEEDED) {
        Snackbar.make(requireView(),
                    R.string.work_completed, Snackbar.LENGTH_SHORT)
                .show();
   }
});

জটিল কাজের প্রশ্ন

WorkManager 2.4.0 এবং উচ্চতর WorkQuery অবজেক্ট ব্যবহার করে সারিবদ্ধ কাজের জন্য জটিল অনুসন্ধান সমর্থন করে। WorkQuery এর ট্যাগ(গুলি), রাজ্য এবং অনন্য কাজের নামের সমন্বয়ে কাজের জন্য অনুসন্ধানকে সমর্থন করে।

নিম্নলিখিত উদাহরণটি দেখায় কিভাবে আপনি ট্যাগ, "syncTag" দিয়ে সমস্ত কাজ খুঁজে পেতে পারেন, যা FAILED বা CANCELLED অবস্থায় আছে এবং " প্রিপ্রসেস " বা " সিঙ্ক " এর একটি অনন্য কাজের নাম রয়েছে৷

কোটলিন

val workQuery = WorkQuery.Builder
       .fromTags(listOf("syncTag"))
       .addStates(listOf(WorkInfo.State.FAILED, WorkInfo.State.CANCELLED))
       .addUniqueWorkNames(listOf("preProcess", "sync")
    )
   .build()

val workInfos: ListenableFuture<List<WorkInfo>> = workManager.getWorkInfos(workQuery)

জাভা

WorkQuery workQuery = WorkQuery.Builder
       .fromTags(Arrays.asList("syncTag"))
       .addStates(Arrays.asList(WorkInfo.State.FAILED, WorkInfo.State.CANCELLED))
       .addUniqueWorkNames(Arrays.asList("preProcess", "sync")
     )
    .build();

ListenableFuture<List<WorkInfo>> workInfos = workManager.getWorkInfos(workQuery);

একটি WorkQuery এর প্রতিটি উপাদান (ট্যাগ, রাজ্য বা নাম) অন্যদের সাথে AND -ed হয়৷ একটি উপাদানের প্রতিটি মান হল OR -ed. উদাহরণস্বরূপ: (name1 OR name2 OR ...) AND (tag1 OR tag2 OR ...) AND (state1 OR state2 OR ...)

WorkQuery LiveData সমতুল্য, getWorkInfosLiveData() এর সাথেও কাজ করে।

বাতিল এবং কাজ বন্ধ

আপনার পূর্বে সারিবদ্ধ কাজ চালানোর জন্য আর প্রয়োজন না হলে, আপনি এটি বাতিল করার জন্য বলতে পারেন। কাজ তার name , id বা এর সাথে যুক্ত tag দ্বারা বাতিল করা যেতে পারে।

কোটলিন

// by id
workManager.cancelWorkById(syncWorker.id)

// by name
workManager.cancelUniqueWork("sync")

// by tag
workManager.cancelAllWorkByTag("syncTag")

জাভা

// by id
workManager.cancelWorkById(syncWorker.id);

// by name
workManager.cancelUniqueWork("sync");

// by tag
workManager.cancelAllWorkByTag("syncTag");

হুডের নিচে, ওয়ার্ক ম্যানেজার কাজের State পরীক্ষা করে। কাজ শেষ হয়ে গেলে কিছুই হবে না। অন্যথায়, কাজের অবস্থা CANCELLED করা হয়েছে এবং কাজটি ভবিষ্যতে চলবে না। এই কাজের উপর নির্ভরশীল যেকোন WorkRequest কাজগুলিও CANCELLED করা হবে।

বর্তমানে RUNNING কাজ ListenableWorker.onStopped() এ একটি কল পায়। যেকোনো সম্ভাব্য পরিচ্ছন্নতা পরিচালনা করতে এই পদ্ধতিটি ওভাররাইড করুন। আরও তথ্যের জন্য একজন চলমান কর্মীকে থামান দেখুন।

একজন চলমান কর্মীকে থামান

আপনার চলমান Worker WorkManager দ্বারা বন্ধ করার কয়েকটি ভিন্ন কারণ রয়েছে:

  • আপনি স্পষ্টভাবে এটি বাতিল করার জন্য বলেছেন (উদাহরণস্বরূপ, WorkManager.cancelWorkById(UUID) কল করে)।
  • অনন্য কাজের ক্ষেত্রে, আপনি স্পষ্টভাবে REPLACE এর একটি ExistingWorkPolicy ওয়ার্ক পলিসি সহ একটি নতুন WorkRequest সারিবদ্ধ করেছেন৷ পুরানো WorkRequest অবিলম্বে বাতিল বলে বিবেচিত হয়৷
  • আপনার কাজের সীমাবদ্ধতা আর পূরণ হয় না।
  • সিস্টেম কোনো কারণে আপনার কাজ বন্ধ করার জন্য আপনার অ্যাপকে নির্দেশ দিয়েছে। আপনি যদি 10 মিনিটের কার্যকর করার সময়সীমা অতিক্রম করেন তবে এটি ঘটতে পারে। কাজটি পরবর্তী সময়ে পুনরায় চেষ্টা করার জন্য নির্ধারিত হয়েছে৷

এই অবস্থার অধীনে, আপনার কর্মী বন্ধ করা হয়.

আপনার প্রগতিতে থাকা যেকোন কাজকে সহযোগিতামূলকভাবে বাতিল করা উচিত এবং আপনার কর্মী যে সংস্থানগুলি ধরে রেখেছেন তা ছেড়ে দেওয়া উচিত। উদাহরণস্বরূপ, আপনার এই সময়ে ডাটাবেস এবং ফাইলগুলির খোলা হ্যান্ডেলগুলি বন্ধ করা উচিত। আপনার কর্মী কখন থামছে তা বোঝার জন্য আপনার হাতে দুটি প্রক্রিয়া রয়েছে।

অনস্টপড() কলব্যাক

আপনার কর্মীকে থামানোর সাথে সাথে WorkManager ListenableWorker.onStopped() আহ্বান করে। আপনার হাতে থাকা কোনো সংস্থান বন্ধ করতে এই পদ্ধতিটি ওভাররাইড করুন।

isStopped() সম্পত্তি

আপনার কর্মী ইতিমধ্যে বন্ধ করা হয়েছে কিনা তা পরীক্ষা করতে আপনি ListenableWorker.isStopped() পদ্ধতিতে কল করতে পারেন। আপনি যদি আপনার ওয়ার্কারে দীর্ঘস্থায়ী বা পুনরাবৃত্তিমূলক ক্রিয়াকলাপগুলি সম্পাদন করেন তবে আপনার এই সম্পত্তিটি ঘন ঘন পরীক্ষা করা উচিত এবং যত তাড়াতাড়ি সম্ভব কাজ বন্ধ করার জন্য এটিকে একটি সংকেত হিসাবে ব্যবহার করা উচিত।

দ্রষ্টব্য: ওয়ার্কম্যানেজার অনস্টপ সিগন্যাল পেয়েছে এমন একজন কর্মী দ্বারা সেট করা Result উপেক্ষা করে, কারণ কর্মী ইতিমধ্যেই বন্ধ বলে বিবেচিত হয়েছে৷