liguofeng29’s blog

個人勉強用ブログだっす。

Androidのイベント処理 - AsyncTask

 サブスレッドがUI更新できないため、Androidが提供しているソリューション。

 
1. Handler
2. Activity.runOnUiThread(Runnable)
3. View.post(Runnable)
4. View.post(Runnable, long)
Handler以外は少し実装が煩雑である(と聞いた・・)
AsyncTaskは簡易方法でスレッドとHandlerを使わずにUI変更できるのだ。

 

AsyncTask<Params, Progress, Result>は抽象クラスである。

Params - タスク起動入力パラメータ型
Progress, タスク完了の進捗値型
Result - 戻り値型

 

AsyncTaskの使用流れ

① AsyncTaskサブクラス生成、パラメータ型指定、パラメータ不要の場合void指定。
② AsyncTaskのメソッド実装(必要に応じて)
doInBackground(Params...) 
- バッググラウンドで実行する処理(publishProgress(Progerss... values)で進捗を更新する)
onPregressUpdate(Progress...) 
- doInBackgroundのpublistProgress実行後に実行する
onPreExecute() 
- バックグラウンド処理の前処理
onPostExecute(Result result) 
- バックグラウンド処理の後処理
③ AsyncTaskのexecute(Params...)実行

 

AsyncTask使用時のルール

① UIスレッド内でAsyncTaskのインスタンス生成
② UIスレッド内でAsyncTaskのexecute()実行
③ AsyncTask内のメソッド(使用流れ②)はAndroidシステムがコールする
④ AsyncTask一回のみに実行する。多重呼び出しは異常を起こす。
 

サンプルコード

MainActivity.java
 
package com.example.liguofeng.asynctasktest;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import java.net.URL;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

public void download(View v) {
HeavyTask task = new HeavyTask(this);
task.execute("実行パラメータ");
}

// ① AsyncTaskのサブクラス作成
class HeavyTask extends AsyncTask<String, Integer, String> {

ProgressDialog progressDialog; // 進捗表示
int progress; // 進捗値
Context context; // メインコンテキスト

public HeavyTask(Context context) {
this.context = context;
}

// ② 事前処理
@Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(context);
progressDialog.setTitle("Downloading");
progressDialog.setMessage("Downloading, plz waiting.");
progressDialog.setCancelable(false); // 取り消し不可
progressDialog.setMax(100); // 最大進捗値
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); // スタイル
progressDialog.setIndeterminate(false); // 進捗を表示する
progressDialog.show();
}

// ② メイン処理
@Override
protected String doInBackground(String... s) {
// 仮想重い処理
try {
progress = 0;
while(progress <= 100) {
Thread.sleep(1000); //1000ミリ秒Sleepする
publishProgress(progress += 10); // 進捗+10
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
// ② 進捗更新された
@Override
protected void onProgressUpdate(Integer... values) {
progressDialog.setProgress(values[0]);
}
// ② 事後処理
@Override
protected void onPostExecute(String s) {
progressDialog.dismiss();
}
}
}