Threads in CoroutineWorker

Für Nutzer mit Kotlin bietet WorkManager erstklassige Unterstützung für Coroutines. Um Fügen Sie work-runtime-ktx in Ihre Gradle-Datei ein. Anstatt Worker zu verlängern, sollten Sie CoroutineWorker verlängern. In diesem Fall ist eine Sperrung Version von doWork(). Wenn Sie beispielsweise ein einfaches CoroutineWorker-Element erstellen möchten, um einige Netzwerkvorgänge auszuführen, gehen Sie so vor:

class CoroutineDownloadWorker(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        val data = downloadSynchronously("https://www.google.com")
        saveData(data)
        return Result.success()
    }
}

Hinweis: CoroutineWorker.doWork() ist eine Sperrung. . Im Gegensatz zu Worker wird dieser Code nicht auf der angegebenen Executor ausgeführt in deinem Configuration. Stattdessen werden sie ist standardmäßig Dispatchers.Default. Sie können dies anpassen, indem Sie Ihre eigene CoroutineContext angeben. Im obigen Beispiel würden Sie dies wahrscheinlich so für Dispatchers.IO ausführen:

class CoroutineDownloadWorker(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        withContext(Dispatchers.IO) {
            val data = downloadSynchronously("https://www.google.com")
            saveData(data)
            return Result.success()
        }
    }
}

CoroutineWorker verarbeitet Unterbrechungen automatisch, indem die Koroutine abgebrochen wird und das Übertragen der Kündigungssignale. Sie brauchen nichts weiter zu tun bei Unterbrechungen.

CoroutineWorker in einem anderen Prozess ausführen

Sie können einen Worker auch an einen bestimmten Prozess binden, indem Sie RemoteCoroutineWorker, eine Implementierung von ListenableWorker.

RemoteCoroutineWorker bindet mit zwei zusätzlichen Argumenten an einen bestimmten Prozess. die Sie als Teil der Eingabedaten beim Erstellen der Arbeitsanfrage bereitstellen: ARGUMENT_CLASS_NAME und ARGUMENT_PACKAGE_NAME.

Im folgenden Beispiel sehen Sie, wie eine Arbeitsanfrage erstellt wird, die an eine bestimmten Prozess:

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(ExampleRemoteCoroutineWorker::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(ExampleRemoteCoroutineWorker.class)
        .setInputData(data)
        .build();

Für jede RemoteWorkerService müssen Sie auch eine Dienstdefinition in Ihre AndroidManifest.xml-Datei:

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

Produktproben