LearnableWorker में थ्रेडिंग

कुछ मामलों में, आपको कस्टम थ्रेडिंग रणनीति देनी पड़ सकती है. इसके लिए उदाहरण के लिए, हो सकता है कि आपको कॉलबैक-आधारित एसिंक्रोनस ऑपरेशन को मैनेज करना पड़े. WorkManager, इस्तेमाल के इस उदाहरण को ListenableWorker. ListenableWorker सबसे बेसिक वर्कर एपीआई है; Worker, CoroutineWorker, और RxWorker ये सभी उपयोगकर्ता इस क्लास के हैं. ऐप्लिकेशन ListenableWorker से सिर्फ़ यह पता चलता है कि काम कब शुरू और बंद होना चाहिए और कब बंद हो जाना चाहिए पूरी तरह से आप पर निर्भर है. काम शुरू करने के सिग्नल को मुख्य साइट पर शुरू किया गया है थ्रेड है, इसलिए यह बहुत ज़रूरी है कि आप अपने चुनें.

ऐब्सट्रैक्ट तरीका ListenableWorker.startWork() इसका ListenableFuture दिखाता है Result. ऐप्लिकेशन ListenableFuture एक लाइटवेट इंटरफ़ेस है: यह एक Future है, जो लिसनर जोड़ने और अपवादों को लागू करने की सुविधा. इस startWork तरीके का इस्तेमाल करने पर, आपको ListenableFuture लौटाना होगा कार्रवाई के पूरा होने पर, इसे Result कार्रवाई के साथ सेट कर दिया जाएगा. आप बना सकते हैं इन दो में से किसी एक तरीके से ListenableFuture इंस्टेंस:

  1. अगर आप Guava का इस्तेमाल करते हैं, तो ListeningExecutorService का इस्तेमाल करें.
  2. या फिर, शामिल करें councurrent-futures और इसका इस्तेमाल करें CallbackToFutureAdapter.

अगर आपको एसिंक्रोनस कॉलबैक के आधार पर कुछ काम पूरे करने हैं, तो कुछ ऐसा करें:

Kotlin

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
        }
    }
}

Java

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 का ListenableFuture हमेशा रद्द हो जाता है रुक जाने की उम्मीद है. CallbackToFutureAdapter का इस्तेमाल करके, आपको सिर्फ़ रद्द करने की प्रक्रिया का पता लगाने के लिए इस तरीके का इस्तेमाल करें:

Kotlin

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
        }
    }
}

Java

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

किसी अलग प्रोसेस में MakeableWorker को चलाना

आप इसका इस्तेमाल करके किसी वर्कर को किसी खास प्रोसेस से बाइंड भी कर सकते हैं RemoteListenableWorker ListenableWorker को लागू करना.

RemoteListenableWorker दो अतिरिक्त आर्ग्युमेंट की मदद से, किसी खास प्रोसेस से बाइंड करता है जिन्हें काम का अनुरोध करते समय, इनपुट डेटा के हिस्से के तौर पर दिया जाता है: ARGUMENT_CLASS_NAME और ARGUMENT_PACKAGE_NAME.

नीचे दिए गए उदाहरण में, काम का अनुरोध करने की जानकारी दी गई है. खास प्रोसेस पर ध्यान दें:

Kotlin

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

Java

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>

सैंपल