AsyncTaskを使った非同期処理|Android開発
通常、UIに変更を加える場合はUIスレッド上で実行する必要があります。しかしAsyncTaskを使用するとその部分を意識しなくて良くなります。
UI操作をUIスレッドで行わずに例外発生というのはよくある事(私だけ?)なので、非常に便利です。
また、UIスレッドへ投げる処理の記述が無くなるため、ソースコードがスッキリします。
※但しdoInBackgroundでUI操作は行えません。ここはあくまで別スレッド扱いみたいですね。
基本的な使い方
下記のようにAsyncTask
を継承したクラスを実装します。各メソッドの役割はこのようになっています。
- onPreExecute
バックグラウンド処理実行前の前処理を行います。(プログレスを表示など) - doInBackground
バックグラウンド処理を行います。 - onProgressUpdate
バックグラウンド処理中の進捗更新を行います。(プログレスを更新など) - onPostExecute
バックグラウンド処理終了時の処理を行います。(プログレスを消去など)
public class SampleAsyncTask extends AsyncTask<Void, Integer, Boolean> {
@Override
protected void onPreExecute() {
}
@Override
protected Boolean doInBackground(Void... params) {
for (int i = 0; i <= 100; i++) {
publishProgress(i);
}
return true;
}
@Override
protected void onProgressUpdate(Integer... progress) {
// このサンプルでは progress[0] が進捗.
}
@Override
protected void onPostExecute(Boolean result) {
}
}
AsyncTask
に指定しているジェネリクスは順番に以下のもの。
doInBackground
の引数の型onProgressUpdate
の引数の型onPostExecute
の引数の型doInBackground
の戻り値は、onPostExecute
の引数になる。onProgressUpdate
はdoInBackground
から呼び出す。doInBackground
以外は実装必須ではない。(必要な場合のみ実装する)
使用例
下記は画像ファイルをバックグラウンドで読み込み、そのオブジェクトをコールバックで通知するものです。
AsyncTask継承クラス
public class BitmapLoadTask extends AsyncTask {
public interface IBitmapLoadCallback {
void onLoadCompleted(Bitmap bmp);
void onLoadFailed();
}
private String mLoadFilepath;
private IBitmapLoadCallback mCallback;
public BitmapLoadTask(String filepath, IBitmapLoadCallback callback) {
if (callback == null) {
callback = new IBitmapLoadCallback() {
@Override
public void onLoadCompleted(Bitmap bmp) { }
@Override
public void onLoadFailed() { }
};
}
mCallback = callback;
mLoadFilepath = filepath;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Bitmap doInBackground(Void... params) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(mLoadFilepath, options);
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Bitmap result) {
if (result == null) {
mCallback.onLoadFailed();
} else {
mCallback.onLoadCompleted(result);
}
}
}
使用例
new BitmapLoadTask("sample.jpg", new BitmapLoadTask.IBitmapLoadCallback() {
@Override
public void onLoadCompleted(Bitmap bmp) {
// 受け取った Bitmap をUIに設定したりする.
// この時、UIスレッドかどうかを意識する必要がない.
}
@Override
public void onLoadFailed() {
}
}).execute();