Belirli durumlarda, özel bir ileti dizisi stratejisi sağlamanız gerekebilir. Örneğin, geri çağırmaya dayalı eşzamansız bir işlem gerçekleştirmeniz gerekebilir.
WorkManager, bu kullanım alanını ListenableWorker
ile destekler.
ListenableWorker
en temel çalışan API'dir.
Worker
,
CoroutineWorker
ve
RxWorker
hepsi bu sınıftan türetilir. ListenableWorker
, yalnızca işin ne zaman başlayıp durması gerektiğini belirtir ve iş parçacığını tamamen size bırakır. İş başlatma sinyali ana iş parçacığında çağrılır. Bu nedenle, seçtiğiniz arka plan ileti dizisine manuel olarak gitmeniz çok önemlidir.
Soyut yöntem ListenableWorker.startWork()
, Result
ListenableFuture
değerini döndürür. ListenableFuture
, basit bir arayüzdür: İşleyici ekleme ve istisnaları yayma işlevi sağlayan bir Future
'dir. startWork
yönteminde, bir ListenableFuture
döndürmeniz gerekir. Bu değer, tamamlandığında işlemin Result
değeriyle ayarlanır. Aşağıdaki iki yöntemden birini kullanarak ListenableFuture
örnekleri oluşturabilirsiniz:
- Guava kullanıyorsanız
ListeningExecutorService
kullanın. - Aksi takdirde,
councurrent-futures
öğesini gradle dosyanıza ekleyin veCallbackToFutureAdapter
kullanın.
Eşzamansız geri çağırmaya dayalı bazı çalışmalar yürütmek isterseniz şunun gibi bir şey yaparsınız:
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; }); } }
Çalışmanız durdurursa ne olur?
İşin durması beklendiğinde bir ListenableWorker
ListenableFuture
her zaman iptal edilir. CallbackToFutureAdapter
kullanırken aşağıdaki gibi iptal işleyici eklemeniz gerekir:
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'ı farklı bir işlemde çalıştırma
Ayrıca, bir ListenableWorker
uygulaması olan RemoteListenableWorker
kullanarak bir çalışanı belirli bir sürece bağlayabilirsiniz.
RemoteListenableWorker
, iş isteğini oluştururken giriş verileri kapsamında sağladığınız ek iki bağımsız değişkenle belirli bir sürece bağlanır: ARGUMENT_CLASS_NAME
ve ARGUMENT_PACKAGE_NAME
.
Aşağıdaki örnek, belirli bir sürece bağlı bir iş isteğinin oluşturulmasını göstermektedir:
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();
Her RemoteWorkerService
için AndroidManifest.xml
dosyanıza bir hizmet tanımı da eklemeniz gerekir:
<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>