サブスレッドが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のexecute()実行
④ 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(); } } }
|