Threading in Worker

Wenn Sie einen Worker verwenden, WorkManager ruft Worker.doWork() automatisch an in einem Hintergrundthread. Der Hintergrundthread stammt aus Executor die im WorkManager-Configuration angegeben sind. Standardmäßig richtet WorkManager eine Executor für Sie ein. Sie können sie aber auch anpassen. Ihren eigenen. Sie können beispielsweise einen vorhandenen Hintergrund-Executor in Ihrem App erstellen, erstellen Sie ein Executor mit einem einzigen Thread, damit die gesamte Arbeit im Hintergrund erledigt wird sequenziell ausführen oder sogar eine benutzerdefinierte Executor angeben. So passen Sie die Executor, Sie müssen WorkManager manuell initialisieren.

Bei der manuellen Konfiguration von WorkManager können Sie Executor angeben als folgt:

Kotlin

WorkManager.initialize(
    context,
    Configuration.Builder()
         // Uses a fixed thread pool of size 8 threads.
        .setExecutor(Executors.newFixedThreadPool(8))
        .build())

Java

WorkManager.initialize(
    context,
    new Configuration.Builder()
        .setExecutor(Executors.newFixedThreadPool(8))
        .build());

Hier ist ein Beispiel für eine einfache Worker, mit der der Inhalt einer Webseite heruntergeladen wird. 100-mal:

Kotlin

class DownloadWorker(context: Context, params: WorkerParameters) : Worker(context, params) {

    override fun doWork(): ListenableWorker.Result {
        repeat(100) {
            try {
                downloadSynchronously("https://www.google.com")
            } catch (e: IOException) {
                return ListenableWorker.Result.failure()
            }
        }

        return ListenableWorker.Result.success()
    }
}

Java

public class DownloadWorker extends Worker {

    public DownloadWorker(Context context, WorkerParameters params) {
        super(context, params);
    }

    @NonNull
    @Override
    public Result doWork() {
        for (int i = 0; i < 100; i++) {
            try {
                downloadSynchronously("https://www.google.com");
            } catch (IOException e) {
                return Result.failure();
            }
        }

        return Result.success();
    }

}

Worker.doWork() ist ein synchrone Anrufe erfolgen – Sie müssen die gesamte Hintergrundarbeit und bis zum Beenden der Methode beendet wird. Wenn Sie eine asynchrone API in doWork() und gibt Result zurück, kann Ihr Callback möglicherweise nicht ordnungsgemäß funktioniert. Wenn Sie in dieser Situation sind, sollten Sie einen ListenableWorker verwenden (siehe Threading in ListenableWorker).

Wenn eine derzeit ausgeführte Worker aus irgendeinem Grund beendet wird, geschieht Folgendes: erhält einen Anruf an Worker.onStopped(). Diese Methode überschreiben oder Worker.isStopped() anrufen um Ihren Code zu überprüfen und bei Bedarf Ressourcen freizugeben. Wenn die Worker im obigen Beispiel gestoppt wurde, kann es sich in der Mitte der Elemente werden heruntergeladen. Dies wird auch nach dem Beenden des Vorgangs fortgesetzt. Bis dieses Verhalten zu optimieren, können Sie beispielsweise Folgendes tun:

Kotlin

class DownloadWorker(context: Context, params: WorkerParameters) : Worker(context, params) {

    override fun doWork(): ListenableWorker.Result {
        repeat(100) {
            if (isStopped) {
                break
            }

            try {
                downloadSynchronously("https://www.google.com")
            } catch (e: IOException) {
                return ListenableWorker.Result.failure()
            }

        }

        return ListenableWorker.Result.success()
    }
}

Java

public class DownloadWorker extends Worker {

    public DownloadWorker(Context context, WorkerParameters params) {
        super(context, params);
    }

    @NonNull
    @Override
    public Result doWork() {
        for (int i = 0; i < 100; ++i) {
            if (isStopped()) {
                break;
            }

            try {
                downloadSynchronously("https://www.google.com");
            } catch (IOException e) {
                return Result.failure();
            }
        }

        return Result.success();
    }
}

Sobald ein Worker angehalten wurde, ist es egal, von wo aus du zurückkehrst Worker.doWork(); wird Result ignoriert.