簡単に知りたい人向け。
AsyncTaskの使用は非推奨になっており、もし外部ライブラリの使用が可能であれば、RxJava2を利用した方法が簡単です。オフィシャルの方法でやるのであれば、今後はAsyncTaskLoaderを利用した方法を学習したほうがいいと思われます。
AsyncTaskを利用するにはAsyncTaskを継承したクラスを作成し、下記のメソッドをoverrideし、そこに様々な処理を記述することで実行する。AndroidStudioには作成しなければならないメソッドを自動的に生成してくれるので、その機能を使うと便利。
ASynvTaskは基本的に以下のような構造になっている。
まず、doInBackgroundメソッドが実際に処理を記述するメソッドで、これが別スレッドで動作する。そのためActivityの動作とは別スレッドで処理されるので、ここでUI部品の操作をすることができない。
onProgressUpdateとonPostExecuteメソッドは、Actibityと同じスレッドで動作するので、このメソッド内ではUI部品にアクセスすることができる。なのでdoInBackGroundから適時、onProgressUpdateとonPostExecuteメソッドを呼び出して実行させることで、別スレッドで動作している処理からUI部品へのアクセスが可能になるというようなことを行っている。
途中経過を実装する場合には処理の途中で適時onProgressUpdateのほうでUI部品に対して実行する。UI部品へアクセスするにはアクティビティ本体を渡してもいいしUI部品のインスタンスを渡してもいいが、クラスのプロパティで設定しておくと楽。
AsyncTaskにはジェネリクスを記述する必要があるが、そこがわかりにくい。
<int, int, int>の第一引数は処理の実行時に渡すパラメータになる。処理開始時に渡す無いようなので、例えばダウンロードするファイル名を渡したり、URLを渡したりするのに利用する。ここはvarargなので引数をいくつでも渡すことができるし、必要なら独自にクラスを作成すればどのような情報でも受け渡し可能になる。
<int, int, int>の第二引数はonProgressUpdateに渡す引数のパラメータになる。onProgressUpdateは処理中の作業の経過状況を表示するメソッドなので、例えばダウンロードしている処理が何%終了しているかなど表示するような処理を行う。
<int, int, int>の第三引数はonPostExecuteに渡す引数のパラメータになる。onPostExecuteは処理が終了したあとに処理した結果を表示するメソッドなので、例えばダウンロードに成功したかどうか、ダウンロードした容量はいくつかなどを表示するような処理を行う。
流れとしては、AsyncTask.execute(第一引数)で実行すると、doinBackground(第一引数)として実行される。doInBackgroundでは、様々な処理をした作業中の経過を表示させるためにonProgressUpdate(第二引数)として実行する。
doInBackGroundでの処理が終わると、doInBackGroundで指定したreturnの返値がonPostExecute(第三引数)の引数として返るので、別スレッドの処理が終了したことをonPostExecuteメソッド内で処理をする。
AsyncTaskの使用は非推奨になっており、もし外部ライブラリの使用が可能であれば、RxJava2を利用した方法が簡単です。オフィシャルの方法でやるのであれば、今後はAsyncTaskLoaderを利用した方法を学習したほうがいいと思われます。
AsyncTaskを利用するにはAsyncTaskを継承したクラスを作成し、下記のメソッドをoverrideし、そこに様々な処理を記述することで実行する。AndroidStudioには作成しなければならないメソッドを自動的に生成してくれるので、その機能を使うと便利。
ASynvTaskは基本的に以下のような構造になっている。
まず、doInBackgroundメソッドが実際に処理を記述するメソッドで、これが別スレッドで動作する。そのためActivityの動作とは別スレッドで処理されるので、ここでUI部品の操作をすることができない。
onProgressUpdateとonPostExecuteメソッドは、Actibityと同じスレッドで動作するので、このメソッド内ではUI部品にアクセスすることができる。なのでdoInBackGroundから適時、onProgressUpdateとonPostExecuteメソッドを呼び出して実行させることで、別スレッドで動作している処理からUI部品へのアクセスが可能になるというようなことを行っている。
途中経過を実装する場合には処理の途中で適時onProgressUpdateのほうでUI部品に対して実行する。UI部品へアクセスするにはアクティビティ本体を渡してもいいしUI部品のインスタンスを渡してもいいが、クラスのプロパティで設定しておくと楽。
AsyncTaskにはジェネリクスを記述する必要があるが、そこがわかりにくい。
<int, int, int>の第一引数は処理の実行時に渡すパラメータになる。処理開始時に渡す無いようなので、例えばダウンロードするファイル名を渡したり、URLを渡したりするのに利用する。ここはvarargなので引数をいくつでも渡すことができるし、必要なら独自にクラスを作成すればどのような情報でも受け渡し可能になる。
<int, int, int>の第二引数はonProgressUpdateに渡す引数のパラメータになる。onProgressUpdateは処理中の作業の経過状況を表示するメソッドなので、例えばダウンロードしている処理が何%終了しているかなど表示するような処理を行う。
<int, int, int>の第三引数はonPostExecuteに渡す引数のパラメータになる。onPostExecuteは処理が終了したあとに処理した結果を表示するメソッドなので、例えばダウンロードに成功したかどうか、ダウンロードした容量はいくつかなどを表示するような処理を行う。
流れとしては、AsyncTask.execute(第一引数)で実行すると、doinBackground(第一引数)として実行される。doInBackgroundでは、様々な処理をした作業中の経過を表示させるためにonProgressUpdate(第二引数)として実行する。
doInBackGroundでの処理が終わると、doInBackGroundで指定したreturnの返値がonPostExecute(第三引数)の引数として返るので、別スレッドの処理が終了したことをonPostExecuteメソッド内で処理をする。
//インスタンスを作成し、プロパティにbuttonの対象を指定して、77を引数として渡して実行する。
//この引数の型はAsyncTaskで記述したジェネリクスの一つ目の変数の型になる
MyAsyncTask().also { it.button = button }.execute(77)
//今回はint、int、intを指定
//最初のintがMyAsyncTask().execure(77)のintであり、doInBackgroundの引数になる
class MyAsyncTask : AsyncTask<int, int, int>() {
//プロパティとしてボタンのインスタンスを格納できるようにしておく
var button: Button? = null
//execute(77)の引数である77がp0に入って実行される
override fun doInBackground(vararg p0: Int?): Int {
//77が表示される
Log.v("nullpo", p0[0].toString())
Thread.sleep(1000*2)
//onProgressUpdateを呼ぶメソッド ここで指定した引数が渡される
publishProgress(88)
//ここで主な処理を行い返値を返す
//ここでUIに対して処理するとエラーになる
return 99
}
//publishProgress(88)の引数である88がvalusに入って実行される
override fun onProgressUpdate(vararg values: Int?) {
super.onProgressUpdate(*values)
//ここで引数に従って何らかの進捗状況の表示処理をする
button?.text = "ぬるんぬるん"
//88が表示される
Log.v("nullpo", values[0].toString())
}
//doInBackgroundの返値である99がresultに入って実行される
override fun onPostExecute(result: Int?) {
super.onPostExecute(result)
//ここで引数に従って何らかの終了処理の表示をする
button?.text = "がっ"
//99が表示される
Log.v("nullpo", result.toString())
}
}