AsyncTask が非推奨になったので代わりに、Executorを使った非同期処理はどう実装するのか見てみます
2021.2.1
非同期処理
非同期処理が必要なケースは、メインスレッドでアプリがUIを表示させたり、ユーザーが入力したりしている裏でいろいろと処理をして欲しい場合です
Google AsyncTask によれば、代わりに
java.util.concurrent or Kotlin concurrency utilities が推奨されています。
ここでは、java.util.concurrent.Executor を使っていきます。
画像などの大きなファイルをダウンロードする場合も非同期を使います
 
尚、AsyncTask はこちらにしばらく残しておきます
非同期処理 AsyncTaskの使い方 (API 30から非推奨)
AsyncTaskの基本的構造
AsynTaskの構造はこうなっていました
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | public class TestTask extends AsyncTask<Integer, Integer, Integer> {     // 前処理     @Override     protected void onPreExecute() {         // ...     }     // 非同期処理     @Override     protected Integer doInBackground(Integer... params) {         return params[0] ;     }     // 途中経過をメインスレッドに返す     @Override     protected void onProgressUpdate(Integer... progress) {         // ...     }     // 非同期処理が終了後、結果をメインスレッドに返す     @Override     protected void onPostExecute(Integer result) { 	// ...     } } | 
 
これをExecutorに当てはめていきますが、
java.util.concurrent.Executorを継承した
ExecutorService から、単一のワーカー・スレッドだけを設定する
newSingleThreadExecutor()
のメソッドを使っていきます
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | ... ExecutorService executorService; executorService = Executors.newSingleThreadExecutor(); ... private class TaskRun implements Runnable {     @Override     public void run() {         Log.d("debug", "doInBackground()");         // 非同期処理         new Handler(Looper.getMainLooper())             .post(() -> onPostExecute());     } } void execute() {     onPreExecute();     executorService.submit(TaskRun()); } void onPreExecute() {     Log.d("debug", "onPreExecute()");     // 前処理 } void onPostExecute() {     Log.d("debug","onPostExecute()");     // 非同期処理が終了後、結果をメインスレッドに返す } | 
サンプルコード
重いTaskを非同期で実行させ結果を表示させるサンプルです
 
MainActivity.java
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | //package your.package.name; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.util.Log; import android.widget.Button; import android.widget.TextView; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class MainActivity extends AppCompatActivity {     private MyTask asyncProgress;     private TextView textView;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         textView = findViewById(R.id.textview);         Button button1 = findViewById(R.id.button);         button1.setOnClickListener( v -> {             textView.setText("0");             asyncProgress = new MyTask(textView);             asyncProgress.execute();         });     }     private static class MyTask {         ExecutorService executorService;         TextView textView;         double num;         public MyTask(TextView textView) {             super();             this.textView   = textView;             executorService  = Executors.newSingleThreadExecutor();         }         private class TaskRun implements Runnable {             @Override             public void run() {                 Log.d("debug", "doInBackground()");                 for (int i = 0; i < 1000000000; i++) {                     num = (double) i / 7 + 0.3;                 }                 new Handler(Looper.getMainLooper())                 .post(() -> onPostExecute(num));             }         }         void execute() {             onPreExecute();             executorService.submit(new TaskRun());         }         void onPreExecute() {             Log.d("debug", "onPreExecute()");             num = 0;         }         void onPostExecute(double number) {             String str = "Total= " +number;             textView.setText(str);             Log.d("debug","onPostExecute() "+str);         }     } } | 
レイアウトです
activity_main.xml
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout     xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:app="http://schemas.android.com/apk/res-auto"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent"     tools:context=".MainActivity">     <TextView         android:id="@+id/textview"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         app:layout_constraintBottom_toBottomOf="parent"         app:layout_constraintEnd_toEndOf="parent"         app:layout_constraintStart_toStartOf="parent"         app:layout_constraintTop_toTopOf="parent"         app:layout_constraintVertical_bias="0.3" />     <Button         android:id="@+id/button"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:text="@string/button"         app:layout_constraintBottom_toBottomOf="parent"         app:layout_constraintEnd_toEndOf="parent"         app:layout_constraintStart_toStartOf="parent"         app:layout_constraintTop_toTopOf="parent"         app:layout_constraintVertical_bias="0.5" /> </androidx.constraintlayout.widget.ConstraintLayout> | 
 
リソースです
strings.xml
| 1 2 3 4 | <resources>     <string name="app_name">TestExecutor</string>     <string name="button">button</string> </resources> | 
 
実行してみます
![[Android] 非同期処理 Executorの使い方 1x1.trans - [Android] 非同期処理 Executorの使い方](https://akira-watson.com/wp-content/themes/simplicity2/images/1x1.trans.gif)
 
 
関連ページ:
- カスタム Listener を interface を使って実装してみる
- 非同期処理 Executorの使い方
- HttpURLConnection POST でデータを送信する
- HttpURLConnection GET で画像をダウンロードする
References:
GoogleのReference
ThreadPoolExecutor | Android Developers
![[Android] 非同期処理 Executorの使い方 http url connection get 00 100x100 - [Android] 非同期処理 Executorの使い方](https://akira-watson.com/wp-content/uploads/2015/10/http-url-connection-get_00-100x100.jpg)
