Tworzenie wątków w instancji roboczej

Gdy używasz Worker, WorkManager automatycznie wywołuje Worker.doWork() w wątku w tle. Wątek w tle pochodzi z Executor określonego w Configuration w usłudze WorkManager. Domyślnie WorkManager konfiguruje dla Ciebie Executor, ale możesz też dostosować własne. Możesz na przykład udostępnić w aplikacji istniejący wykonawca w tle, utworzyć jednowątkowy element Executor, aby mieć pewność, że wszystkie działania w tle będą wykonywane po kolei, a nawet określić niestandardowy Executor. Aby dostosować Executor, zainicjuj ręcznie WorkManager.

Konfigurując usługę WorkManager ręcznie, możesz określić Executor w ten sposób:

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());

Oto przykład prostego elementu Worker, który pobiera zawartość strony 100 razy:

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();
    }

}

Pamiętaj, że Worker.doWork() jest wywołaniem synchronicznym. Musisz wykonać całą swoją pracę w tle w sposób blokujący i zakończyć ją przed zakończeniem działania tej metody. Jeśli wywołasz w doWork() asynchroniczny interfejs API i zwrócisz Result, wywołanie zwrotne może nie działać prawidłowo. Jeśli dotyczy Cię taka sytuacja, rozważ użycie ListenableWorker (patrz Threading in ListenableWorker).

Gdy uruchomiona obecnie aplikacja Worker zostanie zatrzymana z dowolnego powodu, otrzyma wywołanie Worker.onStopped(). Zastąp tę metodę lub wywołaj metodę Worker.isStopped(), aby punkt kontroli kodu i w razie potrzeby zwolnić zasoby. Gdy Worker w przykładzie powyżej zostanie zatrzymany, może się okazać, że jest w trakcie pobierania elementów i będzie to robić mimo zatrzymania. Aby zoptymalizować takie działanie, możesz wykonać następujące czynności:

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();
    }
}

Po zatrzymaniu zdarzenia Worker nie ma znaczenia, co jest zwracane z metody Worker.doWork(). Parametr Result jest ignorowany.