ListenableWorker-এ থ্রেডিং

নির্দিষ্ট পরিস্থিতিতে, আপনাকে একটি কাস্টম থ্রেডিং কৌশল প্রদান করতে হতে পারে। উদাহরণস্বরূপ, আপনাকে একটি কলব্যাক-ভিত্তিক অ্যাসিঙ্ক্রোনাস অপারেশন পরিচালনা করতে হতে পারে। WorkManager ListenableWorker এর সাথে এই ব্যবহারের ক্ষেত্রে সমর্থন করে। ListenableWorker হল সবচেয়ে মৌলিক কর্মী API; Worker , CoroutineWorker , এবং RxWorker সবাই এই শ্রেণী থেকে উদ্ভূত। একজন ListenableWorker শুধুমাত্র তখনই সংকেত দেয় যখন কাজটি শুরু করা উচিত এবং বন্ধ করা উচিত এবং থ্রেডিং সম্পূর্ণভাবে আপনার উপর ছেড়ে দেয়। মূল থ্রেডে কাজ শুরু করার সংকেত দেওয়া হয়, তাই আপনার পছন্দের ব্যাকগ্রাউন্ড থ্রেডে ম্যানুয়ালি যাওয়া খুবই গুরুত্বপূর্ণ।

বিমূর্ত পদ্ধতি ListenableWorker.startWork() Result একটি ListenableFuture প্রদান করে। একটি ListenableFuture হল একটি হালকা ইন্টারফেস: এটি একটি Future যা শ্রোতাদের সংযুক্ত করার এবং ব্যতিক্রমগুলি প্রচার করার জন্য কার্যকারিতা প্রদান করে৷ startWork পদ্ধতিতে, আপনি একটি ListenableFuture ফেরত দেবেন বলে আশা করা হচ্ছে, যেটি আপনি সম্পূর্ণ হয়ে গেলে অপারেশনের Result সাথে সেট করবেন। আপনি দুটি উপায়ের একটিতে ListenableFuture দৃষ্টান্ত তৈরি করতে পারেন:

  1. আপনি যদি পেয়ারা ব্যবহার করেন তবে ListeningExecutorService ব্যবহার করুন।
  2. অন্যথায়, আপনার gradle ফাইলে councurrent-futures অন্তর্ভুক্ত করুন এবং CallbackToFutureAdapter ব্যবহার করুন।

আপনি যদি একটি অ্যাসিঙ্ক্রোনাস কলব্যাকের উপর ভিত্তি করে কিছু কাজ সম্পাদন করতে চান তবে আপনি এইরকম কিছু করবেন:

কোটলিন

class CallbackWorker(
        context: Context,
        params: WorkerParameters
) : ListenableWorker(context, params) {
    override fun startWork(): ListenableFuture<Result> {
        return CallbackToFutureAdapter.getFuture { completer ->
            val callback = object : Callback {
                var successes = 0

                override fun onFailure(call: Call, e: IOException) {
                    completer.setException(e)
                }

                override fun onResponse(call: Call, response: Response) {
                    successes++
                    if (successes == 100) {
                        completer.set(Result.success())
                    }
                }
            }

            repeat(100) {
                downloadAsynchronously("https://example.com", callback)
            }

            callback
        }
    }
}

জাভা

public class CallbackWorker extends ListenableWorker {

    public CallbackWorker(Context context, WorkerParameters params) {
        super(context, params);
    }

    @NonNull
    @Override
    public ListenableFuture<Result> startWork() {
        return CallbackToFutureAdapter.getFuture(completer -> {
            Callback callback = new Callback() {
                int successes = 0;

                @Override
                public void onFailure(Call call, IOException e) {
                    completer.setException(e);
                }

                @Override
                public void onResponse(Call call, Response response) {
                    successes++;
                    if (successes == 100) {
                        completer.set(Result.success());
                    }
                }
            };

            for (int i = 0; i < 100; i++) {
                downloadAsynchronously("https://www.example.com", callback);
            }
            return callback;
        });
    }
}

আপনার কাজ বন্ধ হলে কি হবে? একটি ListenableWorker 's ListenableFuture সর্বদা বাতিল করা হয় যখন কাজ বন্ধ হওয়ার আশা করা হয়। একটি CallbackToFutureAdapter ব্যবহার করে, আপনাকে কেবল একটি বাতিল শ্রোতা যোগ করতে হবে, নিম্নরূপ:

কোটলিন

class CallbackWorker(
        context: Context,
        params: WorkerParameters
) : ListenableWorker(context, params) {
    override fun startWork(): ListenableFuture<Result> {
        return CallbackToFutureAdapter.getFuture { completer ->
            val callback = object : Callback {
                var successes = 0

                override fun onFailure(call: Call, e: IOException) {
                    completer.setException(e)
                }

                override fun onResponse(call: Call, response: Response) {
                    ++successes
                    if (successes == 100) {
                        completer.set(Result.success())
                    }
                }
            }

 completer.addCancellationListener(cancelDownloadsRunnable, executor)

            repeat(100) {
                downloadAsynchronously("https://example.com", callback)
            }

            callback
        }
    }
}

জাভা

public class CallbackWorker extends ListenableWorker {

    public CallbackWorker(Context context, WorkerParameters params) {
        super(context, params);
    }

    @NonNull
    @Override
    public ListenableFuture<Result> startWork() {
        return CallbackToFutureAdapter.getFuture(completer -> {
            Callback callback = new Callback() {
                int successes = 0;

                @Override
                public void onFailure(Call call, IOException e) {
                    completer.setException(e);
                }

                @Override
                public void onResponse(Call call, Response response) {
                    ++successes;
                    if (successes == 100) {
                        completer.set(Result.success());
                    }
                }
            };

            completer.addCancellationListener(cancelDownloadsRunnable, executor);

            for (int i = 0; i < 100; ++i) {
                downloadAsynchronously("https://www.example.com", callback);
            }
            return callback;
        });
    }
}

একটি ভিন্ন প্রক্রিয়ায় একটি ListenableWorker চালানো

আপনি RemoteListenableWorker ব্যবহার করে একজন কর্মীকে একটি নির্দিষ্ট প্রক্রিয়ার সাথে আবদ্ধ করতে পারেন, ListenableWorker এর একটি বাস্তবায়ন।

RemoteListenableWorker দুটি অতিরিক্ত আর্গুমেন্ট সহ একটি নির্দিষ্ট প্রক্রিয়ার সাথে আবদ্ধ হয় যা আপনি কাজের অনুরোধ তৈরি করার সময় ইনপুট ডেটার অংশ হিসাবে প্রদান করেন: ARGUMENT_CLASS_NAME এবং ARGUMENT_PACKAGE_NAME

নিম্নলিখিত উদাহরণটি একটি কাজের অনুরোধ তৈরি করে যা একটি নির্দিষ্ট প্রক্রিয়ার সাথে আবদ্ধ:

কোটলিন

val PACKAGE_NAME = "com.example.background.multiprocess"

val serviceName = RemoteWorkerService::class.java.name
val componentName = ComponentName(PACKAGE_NAME, serviceName)

val data: Data = Data.Builder()
   .putString(ARGUMENT_PACKAGE_NAME, componentName.packageName)
   .putString(ARGUMENT_CLASS_NAME, componentName.className)
   .build()

return OneTimeWorkRequest.Builder(ExampleRemoteListenableWorker::class.java)
   .setInputData(data)
   .build()

জাভা

String PACKAGE_NAME = "com.example.background.multiprocess";

String serviceName = RemoteWorkerService.class.getName();
ComponentName componentName = new ComponentName(PACKAGE_NAME, serviceName);

Data data = new Data.Builder()
        .putString(ARGUMENT_PACKAGE_NAME, componentName.getPackageName())
        .putString(ARGUMENT_CLASS_NAME, componentName.getClassName())
        .build();

return new OneTimeWorkRequest.Builder(ExampleRemoteListenableWorker.class)
        .setInputData(data)
        .build();

প্রতিটি RemoteWorkerService এর জন্য, আপনাকে আপনার AndroidManifest.xml ফাইলে একটি পরিষেবা সংজ্ঞা যোগ করতে হবে:

<manifest ... >
    <service
            android:name="androidx.work.multiprocess.RemoteWorkerService"
            android:exported="false"
            android:process=":worker1" />

        <service
            android:name=".RemoteWorkerService2"
            android:exported="false"
            android:process=":worker2" />
    ...
</manifest>

নমুনা