Worker
를 사용하면 WorkManager는 자동으로 백그라운드 스레드에서 Worker.doWork()
를 호출합니다. 백그라운드 스레드의 출처는 WorkManager의 Configuration
에 명시된 Executor
입니다.
기본적으로 WorkManager에서 개발자를 위해 Executor
를 설정하지만, 개발자가 직접 맞춤설정할 수도 있습니다. 예를 들어 앱에서 기존 백그라운드 Executor를 공유하거나 단일 스레드 Executor
를 만들어 모든 백그라운드 작업이 순차적으로 실행되도록 하거나 맞춤 Executor
를 지정하면 됩니다. Executor
를 맞춤설정하려면 WorkManager를 직접 초기화해야 합니다.
WorkManager를 직접 구성할 때 다음과 같이 Executor
를 지정하세요.
Kotlin
WorkManager.initialize( context, Configuration.Builder() // Uses a fixed thread pool of size 8 threads. .setExecutor(Executors.newFixedThreadPool(8)) .build())
자바
WorkManager.initialize( context, new Configuration.Builder() .setExecutor(Executors.newFixedThreadPool(8)) .build());
다음은 웹페이지 콘텐츠를 100번 다운로드하는 간단한 Worker
의 예입니다.
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() } }
자바
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 { repeat(100) { 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()
에서 무엇을 반환하는지는 중요하지 않습니다.