في بعض الحالات، قد تحتاج إلى تقديم استراتيجية مخصّصة لسلاسل المحادثات. على سبيل المثال، قد تحتاج إلى التعامل مع عملية غير متزامنة قائمة على معاودة الاتصال.
يدعم WorkManager حالة الاستخدام هذه مع
ListenableWorker
.
ListenableWorker
هي أبسط واجهة برمجة تطبيقات للعاملين،
وتشمل Worker
وCoroutineWorker
وRxWorker
كل ذلك من هذه الفئة. لا يشير
ListenableWorker
إلا إلى الوقت الذي يجب أن يبدأ فيه العمل ويتوقف عنده ويترك
سلسلة المحادثات متروكة لك تمامًا. يتم استدعاء إشارة بدء العمل على سلسلة التعليمات
الرئيسية، لذا من المهم جدًا أن تنتقل إلى سلسلة رسائل خلفية من
اختيارك يدويًا.
تعرض طريقة التجريد ListenableWorker.startWork()
ListenableFuture
من Result
. واجهة
ListenableFuture
هي واجهة بسيطة: وهي واجهة Future
توفِّر
وظائف لإرفاق أدوات معالجة البيانات ونشر الاستثناءات. في طريقة
startWork
، من المتوقّع أن تعرض ListenableFuture
الذي ستضبطه مع Result
للعملية بعد اكتمالها. يمكنك إنشاء
ListenableFuture
مثيل بإحدى الطريقتين التاليتين:
- إذا كنت تستخدم Guava، استخدم
ListeningExecutorService
. - بخلاف ذلك، يمكنك تضمين
councurrent-futures
في ملف Grale واستخدام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; }); } }
ماذا يحدث في حال
إيقاف عملك؟
يتم دائمًا إلغاء تفويض ListenableFuture
لـ "ListenableWorker
" عندما يكون من المتوقّع أن يتوقف العمل. وباستخدام 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; }); } }
تشغيل ListenableWorker في عملية مختلفة
يمكنك أيضًا إلزام العامل بعملية محدّدة باستخدام 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>