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

ListenableWorker의 스레딩

특정 상황에서는 맞춤설정 스레딩 전략을 제공해야 합니다. 예를 들어 콜백 기반의 비동기 작업을 처리해야 하는 경우입니다. 이때는 차단 방식으로 작업을 할 수 없기 때문에 Worker를 사용할 수 없습니다. WorkManager는 ListenableWorker를 통해 이 사용 사례를 지원합니다. ListenableWorker는 최저 수준의 작업자 API이며 Worker, CoroutineWorkerRxWorker는 모두 이 클래스에서 파생됩니다. ListenableWorker는 작업을 시작하고 중지해야 할 때 신호를 보내고 스레딩을 전적으로 개발자에게 맡깁니다. 시작 작업 신호는 기본 스레드에서 호출되므로 개발자가 수동으로 선택한 백그라운드 스레드로 이동하는 것이 매우 중요합니다.

추상 메서드 ListenableWorker.startWork()ResultListenableFuture를 반환합니다. ListenableFuture는 가벼운 인터페이스로, 리스너를 연결하고 예외를 전파하는 기능을 제공하는 Future입니다. startWork 메서드는 ListenableFuture를 반환해야 하며 작업이 완료되면 이를 작업 Result로 설정합니다. 다음 두 가지 방법 중 하나로 ListenableFuture를 생성할 수 있습니다.

  1. Guava를 사용한다면 ListeningExecutorService를 사용합니다.
  2. 그러지 않은 경우 gradle 파일에 councurrent-futures를 포함하고 CallbackToFutureAdapter를 사용합니다.

비동기 콜백을 기반으로 하여 작업을 실행하려면 다음과 같이 해야 합니다.

    public class CallbackWorker extends ListenableWorker {

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

        @NonNull
        @Override
        public ListenableFuture<Result> startWork() {
            return CallbackToFutureAdapter.getFuture(completer -> {
                Callback callback = new Callback() {
                    int successes = 0;

                    @Override
                    public void onFailure(Call call, IOException e) {
                        completer.setException(e);
                    }

                    @Override
                    public void onResponse(Call call, Response response) {
                        ++successes;
                        if (successes == 100) {
                            completer.set(Result.success());
                        }
                    }
                };

                for (int i = 0; i < 100; ++i) {
                    downloadAsynchronously("https://www.google.com", callback);
                }
                return callback;
            });
        }
    }
    

작업이 중지되면 어떻게 되나요? 작업이 중지될 것으로 예상되면 ListenableWorkerListenableFuture는 항상 취소됩니다. CallbackToFutureAdapter를 사용하면 다음과 같이 간단히 취소 리스너를 추가하면 됩니다.

    public class CallbackWorker extends ListenableWorker {

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

        @NonNull
        @Override
        public ListenableFuture<Result> startWork() {
            return CallbackToFutureAdapter.getFuture(completer -> {
                Callback callback = new Callback() {
                    int successes = 0;

                    @Override
                    public void onFailure(Call call, IOException e) {
                        completer.setException(e);
                    }

                    @Override
                    public void onResponse(Call call, Response response) {
                        ++successes;
                        if (successes == 100) {
                            completer.set(Result.success());
                        }
                    }
                };

                completer.addCancellationListener(cancelDownloadsRunnable, executor);

                for (int i = 0; i < 100; ++i) {
                    downloadAsynchronously("https://www.google.com", callback);
                }
                return callback;
            });
        }
    }