[Android] 非同期処理 AsyncTaskの使い方 (API 30から非推奨)

非同期処理が必要なケースは、メインスレッドでアプリがUIを表示させたり、ユーザーが入力したりしている裏でいろいろと処理をして欲しい場合です。(API 30から非推奨)

Android Studio 3.6.3
API 29




AsyncTask

 

(注)  AsyncTask によるとこのAPI 30から非推奨となったようです。
代案は、java.util.concurrent あるいは Kotlin concurrency utilities のようです

非同期にはHandlerやThreadを使いますが、そのHelper ClassとしてAsyncTaskがあり簡単に非同期を扱うことができます。

また、GoogleのReferenceによれば、スレッドを長期間継続させる場合には使用せず、数秒程度の処理にすべきとのことです。
 

 

AsyncTaskの基本的構造

 
AsynTaskはbackground Threadで実行されその結果をUI threadに表示させます。基本的な構造は、


 
非同期を実装するためにAsyncTaskを継承して作ります。
 


 
<Param, …>はジェネリクスな変数を意味しています。
 
変数型にはInteger型やString型などがあるのですが、それぞれのデータ型で同じように処理することが出来きるようにするためのものです、なのでここにはStringやIntegerなどを入れて使えます。
 
その変数は3つのメソッドに関連しています

  • doInBackground(Params…)
    • バックグラウンドでの非同期処理、何か重い処理を記述する
    • ここに渡されるパラメータの型は1つめのParams
  • onProgressUpdate(Progress…)
    • 途中経過をメインスレッドで表示する場合
    • doInBackground内でpublishProgressを設定するとメインスレッドから呼ばれ、パラメータの型は2つめのProgress
  • onPostExecute(Result)
    • バックグラウンドでの非同期処理が終了後メインスレッドに結果を返す
    • パラメータは3つめのResult

このクラスの非同期を実行させるためにはexecute(…)をメインスレッドから呼び出します。実際に使ってみましょう。

 

AsyncTaskの実装

 
このサンプルは重たい処理として1秒間のスリープを10回繰り返し、毎回のスリープをListenerで知らせてViewに表示させる例です。

非同期の他にinterfaceを使ってListenerを実装していますが、それは後半に出てきます。
 
MainActivity.java


 
非同期処理を行うクラスです。パラメータはintを使いたいのですが、ジェネリックに指定できるのは参照型のみで基本型のintは使えません。それでIntegerでラッパークラスを使用します。

TestTask.java


 
レイアウトです
activity_main.xml


 
リソースです
strings.xml


 

 

AsyncTaskのwarning

 
「This field leaks a context object …」
こんな warning でこのページを見つけたのであれば、ドンピシャです。
 
1x1.trans - [Android] 非同期処理 AsyncTaskの使い方 (API 30から非推奨)


 
非同期側からActivityやViewのインスタンスを参照するとリークするぞという警告です。非同期の作業が終わったらTextViewで結果を表示させようとした例です。
WeakReferenceにするという方法もありますが、どうもしっくり来ないと思っていたところ同じ気持ちの人を発見しました。
 
You don’t have to use WeakReference to avoid memory leaks
 
Novodaのエキスパートらしいのですが、WeakReferenceは最終手段でNovodaでは使っとらへんでーということらしいです。Listenerを使うのですが、至極理にかなっていますね。
 
非同期作業を別にやらせているので、メインスレッドからはいつ作業が終わるのかわかりません。毎回ポーリングするのは無駄が多いですし、作業が終わったら教えてくれればいいのです。それを聞く耳は立てておくということでしょう。
 
Listenerを独自に作成する方法はこちらを参照してください。

https://akira-watson.com/android/custom-listener.html

余談ですが、syncは同期という意味合いですが、asyncで言う「a」は接頭辞で「not」の意味を持ちます。リスニングでは聞き逃しそうですね。
 
 
関連ページ:

References:
GoogleのReference
ThreadPoolExecutor | Android Developers

シェアする

  • このエントリーをはてなブックマークに追加

フォローする