Google은 흑인 공동체를 위한 인종 간 평등을 진전시키기 위해 노력하고 있습니다. Google에서 어떤 노력을 하고 있는지 확인하세요.

작업자의 스레딩

Worker를 사용하면 WorkManager는 자동으로 백그라운드 스레드에서 Worker.doWork()를 호출합니다. 백그라운드 스레드는 WorkManager의 Configuration에 명시된 Executor에서 가져옵니다. 기본적으로 WorkManager에서 Executor를 설정하지만, 개발자가 직접 맞춤설정할 수도 있습니다. 예를 들어, 앱에서 기존 백그라운드의 Executor를 공유하거나 Executor를 단일 스레드로 만들어서 모든 백그라운드 작업이 직렬로 실행되도록 하거나 또는 다양한 스레드 수로 ThreadPool을 지정할 수 있습니다. Executor를 맞춤설정하려면 WorkManager 수동 초기화를 사용 설정해야 합니다. WorkManager를 구성할 때는 다음과 같이 Executor를 지정하면 됩니다.

Kotlin

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

자바

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

다음은 일부 웹 사이트의 콘텐츠를 순차적으로 다운로드하는 간단한 작업자의 예입니다.

Kotlin

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

    override fun doWork(): ListenableWorker.Result {
        for (i in 0..99) {
            try {
                downloadSynchronously("https://www.google.com")
            } catch (e: IOException) {
                return ListenableWorker.Result.failure()
            }
        }

        return ListenableWorker.Result.success()
    }
}

자바

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()는 동기 호출입니다. 즉, 전체 백그라운드 작업을 차단 방식으로 실행하고 메서드가 종료될 때까지 작업을 완료해야 합니다. doWork()에서 비동기 API를 호출하고 Result를 반환하면, 콜백이 제대로 작동하지 않을 수 있습니다. 이런 상황에서는 ListenableWorker를 사용하는 것이 좋습니다(ListenableWorker의 스레딩 참고).

현재 실행 중인 Worker어떤 이유로든 중지되면 작업자는 Worker.onStopped()를 수신합니다. 필요한 경우 이 메서드를 재정의하거나 Worker.isStopped()를 호출하여 코드에 체크포인트를 설정하고 리소스를 해제합니다. 위의 예에서는 Worker가 중지될 때 항목을 다운로드하는 루프 안에 있을 수 있고 작업자가 중지되었는데도 실행이 계속됩니다. 이 동작을 최적화하려면 다음과 같이 하면 됩니다.

Kotlin

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

    override fun doWork(): ListenableWorker.Result {
        for (i in 0..99) {
            if (isStopped) {
                break
            }

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

        }

        return ListenableWorker.Result.success()
    }
}

자바

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

일단 Worker가 중지되면 Result는 무시되므로 Worker.doWork()에서 무엇을 반환하는지는 중요하지 않습니다.