본문 바로가기
개발/Android

[Android] ExecutorService를 이용해 AsyncTask 대체하기

by 준그래머 2023. 7. 20.
반응형

개요

Wallpaper를 자동으로 적용시켜야 하는 작업을 하게 되었다.

시나리오는 아래와 같다.

  1. 적용할 Wallpaper를 전달
  2. Wallpaper가 전달되는 동안 Loading 화면을 보여줌
  3. 세팅이 끝나면 Loading 화면을 닫고 설정이 완료되었다는 것을 유저에게 인지 시킴

위 시나리오처럼 동기 처리가 필요하기 때문에 AsnycTask를 사용하면 그렇게 어렵지 않게 작업할 수 있었지만 이미 deprecated 된 AsyncTask 클래스를 쓴다는 게 조금 찝찝해 ExecutorService와 Handler, Callable를 이용해 구현해 보았다.

 

코드

AutoSetWallpaperRunner 클래스는 ExecutorService로 Callable클래스를 호출하고 콜백 해줄 클래스다.

class AutoSetWallpaperRunner {

    private final ExecutorService service = Executors.newSingleThreadExecutor();
    private final Handler resultHandler = new Handler(Looper.getMainLooper());

    public interface CallbackTask {
        void onComplete(Boolean result);
    }

    public void executeAsync(Callable<Boolean> callable, CallbackTask callbackTask){

        service.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    final Boolean result = callable.call();
                    resultHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            callbackTask.onComplete(result);
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

Callable 클래스에서 call 함수를 요청하고 결과 값을 리턴 받는다. 리턴 받은 값을 Handler를 통해 작업이 끝나면 CallbackTask의 onComplete 함수로 콜백해 준다. 콜백 시 UI 처리가 필요한 경우 Handler는 MainLooper로 선언되어 있어야 한다.

 

 

AutoSetWallpaperTask는 직접적으로 Wallpaper를 적용시킬 클래스며 연산처리할 알맹이라고 보면 된다.

class AutoSetWallpaperTask implements Callable<Boolean>{

    Context context;
    Bitmap bitmap;

    public AutoSetWallpaperTask(Context context, Bitmap bitmap) {
        this.context = context;
        this.bitmap = bitmap;
    }

    @Override
    public Boolean call() throws Exception {
        try {
            WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
            wallpaperManager.setBitmap(bitmap);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }
}

call 함수에서 필요한 연산처리를 하고 타입에 맞게 리턴해 준다.

 

 

결론

간단하게 한 가지의 동기 처리만 구현해 보았지만 List<Callable>과 Executors.newFixedThreadPool(2 이상)을 이용하면 여러 개의 작업을 처리할 수 도 있다.

 

 

참조

 

How to wait for all threads to finish, using ExecutorService?

I need to execute some amount of tasks 4 at a time, something like this: ExecutorService taskExecutor = Executors.newFixedThreadPool(4); while(...) { taskExecutor.execute(new MyTask()); } //.....

stackoverflow.com

 

반응형