カテゴリー: Android

Android 11でdeprecatedになったAsyncTask対応Java編

はじめに

タイトルの通りAndroid 11にて、AsyncTaskがdeprecatedになってしまったので、今回は呼び出し元になるべく影響を与えないように、Android 11対応を行っていきたいと思います。

基本的な対応

以下のようなAsyncTaskがあるとします。

class sampleAsyncTask extends AsyncTask<Void, Void, String> {
 sampleAsyncTask() {
 }

 @Override
 protected void onPreExecute() {
  
 }

 @Override
 protected String doInBackground(Void... void) {
  
 }

 @Override
 protected void onPostExecute(String result) {
  
 }
}

これを置き換えて行きます。

対応後のサンプル

class sampleAsyncTask {
 private class AsyncRunnable implements Runnable {

  private String result;

  Handler handler = new Handler(Looper.getMainLooper());
  @Override
  public void run() {
   onPreExecute();
   result = doInBackground();
   handler.post(new Runnable() {
    @Override
    public void run() {
     onPostExecute(result);
    }
   });
  }
 }

 public void execute() {
  ExecutorService executorService  = Executors.newSingleThreadExecutor();
  executorService.submit(new AsyncRunnable());
 }

 void onPreExecute() {
  
 }

 String doInBackground() {
  
 }

 void onPostExecute(String result) {
  
 }
}

基本的にはRunnableクラスを作成しExecutorServiceで起動するようにします。呼び出し元に影響を与えないようにexecuteメソッドを用意しRunnableを呼び出します。AsyncTask同様に、onPreExecute、doInBackground、onPostExecuteの順番で呼び出されるようにします。一つ注意をするならば、以下のようにHandlerの宣言もdeprecatedされているので気をつけるようにしてください。

// deprecated
//Handler handler = new Handler();

Handler handler = new Handler(Looper.getMainLooper());

また、onPostExecuteをHandler内で呼び出しているのは、UIの更新をかけることを想定しています。

cancelとonCancelled

class sampleAsyncTask {

 boolean canceled;

 private class AsyncRunnable implements Runnable {

  private String result;

  Handler handler = new Handler(Looper.getMainLooper());
  @Override
  public void run() {
   onPreExecute();
   result = doInBackground();
   handler.post(new Runnable() {
    @Override
    public void run() {
     if (!canceled) {
      onPostExecute();
     } else {
      onCancelled();
     }
    }
   });
  }
 }

 public void execute() {
  ExecutorService executorService  = Executors.newSingleThreadExecutor();
  executorService.submit(new AsyncRunnable());
 }

 void onPreExecute() {
  
 }

 String doInBackground() {
  cancel(true);
 }

 void onPostExecute(String result) {
  
 }

 void cancel(Boolean flag) {
  canceled = flag;
 }

 void onCancelled() {
  
 }
}

doInBackground内で何かあったときに、AsyncTaskのcancelを使用するパターンがあると思いますので、今回はこのようにサンプルを用意させてもらいました。AsyncTaskの処理の流れと同様に、cancelされた時はonPostExecuteではなく、onCancelledを呼ぶようにしています。

execute().get()への対応

AsyncTaskを使用しているときに、処理の終了を待つためにexecute().get()を使用することもあると思います。Runnableクラスでは戻り値を返せないので、この場合はCallableクラスを使用します。

class sampleAsyncTask {
 private class AsyncCallable implements Callable<String> {

  @Override
  public String call() throws Exception {
   String result = doInBackground();
   return result;
  }
 }

 public String execute() {
  ExecutorService executorService  = Executors.newSingleThreadExecutor();
  try {
   return executorService.submit(newAsyncCallable()).get();
  } catch (ExecutionException e) {
   e.printStackTrace();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  return null;
 }

 String doInBackground() {
  
 }
}

サンプルではCallableクラスを使用し、Stringを返却するように作成しました。ExecutorServiceのgetを使用することで、処理の終了まで待つことができるようになります。

最後に

deprecatedになったとはいえ、まだすぐに使えなくなるわけではないですが、今後のためにメンテナンスはしていきたいと思います。

おすすめ書籍

nukky

シェア
執筆者:
nukky
タグ: AndroidJava

最近の投稿

フロントエンドで動画デコレーション&レンダリング

はじめに 今回は、以下のように…

3週間 前

Goのクエリビルダー goqu を使ってみる

はじめに 最近携わっているとあ…

4週間 前

【Xcode15】プライバシーマニフェスト対応に備えて

はじめに こんにちは、suzu…

2か月 前

FSMを使った状態管理をGoで実装する

はじめに 一般的なアプリケーシ…

3か月 前