Dalam situasi tertentu, Anda mungkin perlu menyediakan strategi threading kustom. Sebagai
misalnya, Anda mungkin perlu menangani operasi asinkron berbasis callback.
WorkManager mendukung kasus penggunaan ini dengan
ListenableWorker
ListenableWorker
adalah API pekerja paling dasar;
Worker
,
CoroutineWorker
, dan
RxWorker
semuanya berasal dari class ini. J
ListenableWorker
hanya memberikan sinyal kapan pekerjaan harus dimulai, dihentikan, dan berangkat
proses threading, terserah Anda. Sinyal mulai kerja dipanggil di
jadi sangat penting bagi Anda untuk membuka utas latar belakang
pilihan secara manual.
Metode abstrak
ListenableWorker.startWork()
menampilkan ListenableFuture
dari
Result
. J
ListenableFuture
adalah antarmuka yang ringan: ini adalah Future
yang menyediakan
fungsi untuk melampirkan pemroses dan menerapkan pengecualian. Di kolom
startWork
, Anda diharapkan menampilkan ListenableFuture
, yang
akan ditetapkan dengan Result
operasi setelah selesai. Anda dapat membuat
ListenableFuture
instance dengan salah satu dari dua cara berikut:
- Jika Anda menggunakan Guava, gunakan
ListeningExecutorService
. - Atau, sertakan
councurrent-futures
dalam file gradle Anda dan gunakanCallbackToFutureAdapter
.
Jika ingin menjalankan beberapa tugas berdasarkan callback asinkron, Anda perlu lakukan sesuatu seperti ini:
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; }); } }
Apa yang terjadi jika
pekerjaan Anda
dihentikan?
ListenableFuture
ListenableWorker
selalu dibatalkan saat pekerjaan
diperkirakan akan berhenti. Dengan menggunakan CallbackToFutureAdapter
, Anda hanya perlu menambahkan
pemroses pembatalan, sebagai berikut:
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; }); } }
Menjalankan ListenableWorker dalam proses yang berbeda
Anda juga dapat mengikat pekerja ke proses tertentu menggunakan
RemoteListenableWorker
,
implementasi ListenableWorker
.
RemoteListenableWorker
terikat ke proses tertentu dengan dua argumen tambahan
yang Anda berikan sebagai bagian dari data input saat membuat permintaan pekerjaan:
ARGUMENT_CLASS_NAME
dan ARGUMENT_PACKAGE_NAME
.
Contoh berikut menunjukkan pembuatan permintaan pekerjaan yang terikat dengan proses tertentu:
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();
Untuk setiap RemoteWorkerService
, Anda juga perlu menambahkan definisi layanan di
file 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>