AsyncTaskでプログレスバーを出してみる


2014年5月29日現在、私が理解している内容です。
間違っている場合があります。


AsyncTaskを使ってみる。


AsynkTaskは、画像ロードなど、何か重い処理をさせたいとき、アプリが重くなったり止まったりしないように、
非同期処理の別のタスクとして仕事させておくというものです。

AsynkTaskは、「タイマーとかスレッドのテスト」でテストしてみたThreadとは違い、
setTextでテキスト変更など、UI(画面)にアクセスする場合に、
いちいちHandler#post()でrun()の中にsetTextを入れ子にしなくてもいいらしいという、便利そうなものです。



タイマーでカウントさせつつ、別途にAsynkTaskでカウントを開始させるテスト。
 

「AsynkTask」ボタンを押すとカウントを始めます。
ボタンを何度も押すと、「Progress」の値がおかしくなります。
AsynkTaskが複数同時起動され、カウントが並行処理されたためです。
「AsyncTaskRunCount1」が、現在実行中のAsynkTaskの数です。
そもそもAsynkTaskから外部の変数を参照するのは、あまりよろしくないコードだと思いますが、
とりあえず「注意しないとこういう不具合が出るよ」というテストということで。

複数同時起動させないためには、ToAsyncTask1()の、「実行中ならリターン」のコードを有効にします。




MainActivity.java

package com.example.test33; import java.util.Timer; import java.util.TimerTask; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.os.AsyncTask; import android.os.Bundle; import android.app.Activity; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; public class MainActivity extends Activity { TextView text1; TextView text2; TextView text3; TextView text4; Timer timer1 = new Timer(); static int TimerCount1 = 0; private AsyncTask<Long, Integer, String> mAsyncTask1; static int AsyncTaskCount1=0; static int AsyncTaskRunCount1=0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout layout1 = new LinearLayout(this); setContentView(layout1); layout1.setOrientation(LinearLayout.VERTICAL); //縦に並ぶ text1 = new TextView(this); layout1.addView(text1); text2 = new TextView(this); layout1.addView(text2); text3 = new TextView(this); layout1.addView(text3); text4 = new TextView(this); layout1.addView(text4); Button button1 = new Button(this); button1.setText("AsyncTask"); layout1.addView(button1); button1.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { //AsyncTaskでカウントをはじめる ToAsyncTask1(TimerCount1); } }); //タイマータスクで一定時間おきにカウントする ToTimerTask1(); } private void ToTimerTask1(){ timer1.scheduleAtFixedRate(new TimerTask() { @Override public void run() { runOnUiThread(new Runnable() { public void run() { text1.setText("TimerCount1 / AsyncTaskRunCount1= " + String.valueOf(TimerCount1 ) + " / " + String.valueOf(AsyncTaskRunCount1)); } }); TimerCount1 += 1; } }, 0, 1000); } public void ToAsyncTask1(int count1){ /* // 実行中ならリターン if (mAsyncTask1 != null && mAsyncTask1.getStatus() == AsyncTask.Status.RUNNING) { Log.d("TAG_ASYNCTASK", "return - " + String.valueOf(AsyncTaskCount1)); return; } */ mAsyncTask1 = new AsyncTaskTest1(count1); //executeの引き数は、doInBackgroundのParamsの値//配列にできる mAsyncTask1.execute(100L,1000L,5000L,0L); } //----------------------------------------------------------------------------------- public class AsyncTaskTest1 extends AsyncTask<Long, Integer, String>{ int AsyncTaskStartCount1=0; int AsyncTaskStopCount1=0; //コンストラクタ public AsyncTaskTest1(int count1){ AsyncTaskStartCount1=count1; AsyncTaskRunCount1++; } @Override protected void onPreExecute() { //タスク開始 Log.d("TAG_ASYNCTASK", "onPreExecute"); text3.setText( "AsyncTask 起動タイミング = "+String.valueOf(AsyncTaskStartCount1)); } @Override protected String doInBackground(Long... params) { //タスク実行 Log.d("TAG_ASYNCTASK", "doInBackground"); //paramsは、mAsyncTask1.executeの引数 for(int i=0;i<params[0];i++){ // 少し待つ try{Thread.sleep(100); } catch( InterruptedException e){ } AsyncTaskCount1++; //onProgressUpdateのvaluesに値を渡す//配列にできる publishProgress(AsyncTaskCount1,i+1); } AsyncTaskStopCount1=TimerCount1; //処理が終了したとき、onPostExecuteのresultに渡す return String.valueOf(AsyncTaskStopCount1); } @Override protected void onProgressUpdate(Integer... values) { //Log.d("TAG_ASYNCTASK", "onProgressUpdate"); //valuesは、publishProgressの引数 //進捗状況が得られるので、 //プログレスバーなどにvaluesの値を入れる text2.setText( "AsyncTask Count= " + String.valueOf(values[0]) + " Progress = " + String.valueOf(values[1])); } @Override protected void onPostExecute(String result) { Log.d("TAG_ASYNCTASK", "onPostExecute"); //処理が終了した //resultは、doInBackgroundからの戻り値 text4.setText( "AsyncTask 終了タイミング = " + result); AsyncTaskRunCount1--; } } }






AsyncTaskの使い方。


AsyncTaskを使うには、はじめに3つのパラメータを設定する必要があります。
AsyncTaskの内部で使用されるパラメータの型です。


AsyncTask<Params, Progress, Result>

Params executeの引数doInBackgroundのparamsに渡される可変なので配列として受け取れる
Progress publishProgressの引数onProgressUpdateのvaluesに渡される可変なので配列として受け取れる
Result doInBackgroundの戻り値onPostExecuteのresultに渡される

Params、Progress、Resultの型は、任意に設定できます。
実際にコードに記述する場合は、型を書きます。
AsyncTaskTest1の例では、Long, Integer, Stringの3つの型を定義しています。


AsyncTask<Long, Integer, String>

値を渡す必要がなければ、Voidを使います。




AsyncTaskのクラスを作る。


はじめに、AsyncTaskを継承したクラスを作ります。

AsyncTaskのパラメータとして設定したLong, Integer, Stringの型は、
doInBackground(),onProgressUpdate(),onPostExecute()から渡されます。
記述するときは、決めたパラメータと違う型を書くとエラーになるので注意しましょう。


public class AsyncTaskTest1 extends AsyncTask<Long, Integer, String>{ //コンストラクタ public AsyncTaskTest1(int count1){ } @Override protected void onPreExecute() { //タスク開始 } @Override protected String doInBackground(Long... params) { //タスク実行 //paramsは、executeの引数 int values = 0; String result = null; publishProgress(values); //処理が終了したとき、onPostExecuteのresultに渡す return result; } @Override protected void onProgressUpdate(Integer... values) { //valuesは、publishProgressの引数 //進捗状況が得られるので、 //プログレスバーなどにvaluesの値を入れる } @Override protected void onPostExecute(String result) { //処理が終了した //resultは、doInBackgroundからの戻り値 } }


AsyncTaskTest1の呼び出し方。


private AsyncTask<Long, Integer, String> mAsyncTask1; .......... mAsyncTask1 = new AsyncTaskTest1(count1); //executeの引き数は、doInBackgroundのParamsの値//配列にできる mAsyncTask1.execute(100L,1000L,5000L,0L);

次のようにも、書けます。

new AsyncTaskTest1(count1).execute(100L);

次のようにも、書けます。

new AsyncTask<Long, Integer, String>() { ..................... @Override protected Void doInBackground(Void... params) { ..................... } ..................... }.execute(100L);


count1は、コンストラクタに渡されます。
executeの引数が、doInBackground()に渡されます。
doInBackground()で実行する処理を書きますが、進捗状況をUIに知らせようと、ここにsetTextなんかを書くとエラーになります。

プログレスバーなどを出して、進捗状況を知らせる場合、
doInBackground()の中で、publishProgress()を呼び出します。
するとonProgressUpdate()が呼ばれますので、そこでUIの操作ができます。





プログレスダイアログを出す。


AsyncTaskから、プログレスダイアログを出すテスト。
スピナーでくるくる、進捗不確定モード、プログレスバー。
   


以下を追加修正する。

import android.app.ProgressDialog; import android.content.Context; ................ public void ToAsyncTask1(int count1){ mAsyncTask1 = new AsyncTaskTest1(this,count1); //executeの引き数は、doInBackgroundのParamsの値//配列にできる mAsyncTask1.execute(100L,1000L,5000L,0L); } ................ public class AsyncTaskTest1 extends AsyncTask<Long, Integer, String>{ int AsyncTaskStartCount1=0; int AsyncTaskStopCount1=0; ProgressDialog dialog; Context context; //コンストラクタ public AsyncTaskTest1(Context context,int count1){ this.context = context; AsyncTaskStartCount1=count1; AsyncTaskRunCount1++; } @Override protected void onPreExecute() { //タスク開始 Log.d("TAG_ASYNCTASK", "onPreExecute"); text3.setText( "AsyncTask 起動タイミング = "+String.valueOf(AsyncTaskStartCount1)); //ダイアログを出す dialog = new ProgressDialog(context); dialog.setTitle("おまちください"); dialog.setMessage("実行中"); //dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);//くるくる //dialog.setIndeterminate(true);//進捗不確定モード dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);//プログレスバー dialog.setMax(100); dialog.setProgress(0); dialog.show(); } @Override protected String doInBackground(Long... params) { //タスク実行 Log.d("TAG_ASYNCTASK", "doInBackground"); //paramsは、mAsyncTask1.executeの引数 for(int i=0;i<params[0];i++){ // 少し待つ try{Thread.sleep(100); } catch( InterruptedException e){ } AsyncTaskCount1++; //onProgressUpdateのvaluesに値を渡す//配列にできる publishProgress(AsyncTaskCount1,i+1); } //onPostExecuteのresultに渡す return String.valueOf(AsyncTaskStopCount1); } @Override protected void onProgressUpdate(Integer... values) { //Log.d("TAG_ASYNCTASK", "onProgressUpdate"); //valuesは、publishProgressの引数 //進捗状況が得られるので、 //プログレスバーなどにvaluesの値を入れる dialog.setProgress(values[1]); text2.setText( "AsyncTask Count= " + String.valueOf(values[0]) + " Progress = " + String.valueOf(values[1])); } @Override protected void onPostExecute(String result) { Log.d("TAG_ASYNCTASK", "onPostExecute"); //処理が終了した //resultは、doInBackgroundからの戻り値 text4.setText( "AsyncTask 終了タイミング = " + result); AsyncTaskRunCount1--; //ダイアログが出ていたら消す if(dialog != null && dialog.isShowing()) { dialog.dismiss(); } } }



「戻るキー」でキャンセルさせる。


「戻るキー」でキャンセルさせるために、リスナーを登録する。

以下のように、ダイアログに、setOnCancelListenerを登録すると、
「戻るキー」で、ダイアログが閉じるようになる。

import android.content.DialogInterface.OnCancelListener; ................ protected void onPreExecute() { //ダイアログを出す dialog = new ProgressDialog(context); dialog.setCancelable(true); dialog.setOnCancelListener(new OnCancelListener(){ @Override public void onCancel(DialogInterface dialog) { // TODO 自動生成されたメソッド・スタブ Log.d("TAG_ASYNCTASK", "onCancel"); cancel(true); } }); }


この場合、ダイアログが閉じても、AsynkTaskは続行されたままになる。
AsynkTaskを止める場合は、cancel(true)を使う。

しかし、上記のようにonCancel(DialogInterface dialog) {}の中から、直接AsynkTaskのcancel(true)を呼び出そうとするとエラーになる。
そこで、AsyncTaskTest1に、OnCancelListenerを、implements する。
AsyncTaskTest1から直接onCancel(DialogInterface dialog) を呼び出し、その中で、AsynkTaskのcancel(true)を呼び出せるようにする。

cancel(true)が実行されると、AsyncTaskのonCancelled()が呼び出される。
が、何もしなければ、doInBackground()で処理は実行されたままになるので、
doInBackground()の処理を中断させるコードを書かなければいけない。
isCancelled()で、キャンセルされたか知ることができるので、以下のように書いてみる。


import android.content.DialogInterface.OnCancelListener; ................ public class AsyncTaskTest1 extends AsyncTask<Long, Integer, String> implements OnCancelListener{ int AsyncTaskStartCount1=0; int AsyncTaskStopCount1=0; ProgressDialog dialog; Context context; //コンストラクタ public AsyncTaskTest1(Context context,int count1){ this.context = context; AsyncTaskStartCount1=count1; AsyncTaskRunCount1++; } @Override protected void onPreExecute() { //タスク開始 Log.d("TAG_ASYNCTASK", "onPreExecute"); text3.setText( "AsyncTask 起動タイミング = "+String.valueOf(AsyncTaskStartCount1)); //ダイアログを出す dialog = new ProgressDialog(context); dialog.setTitle("おまちください"); dialog.setMessage("実行中"); //dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);//くるくる //dialog.setIndeterminate(true);//進捗不確定モード dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);//プログレスバー dialog.setMax(100); dialog.setProgress(0); //ダイアログをキャンセルできるようにする dialog.setCancelable(true); dialog.setOnCancelListener(this); dialog.show(); } @Override protected String doInBackground(Long... params) { //タスク実行 Log.d("TAG_ASYNCTASK", "doInBackground"); //paramsは、mAsyncTask1.executeの引数 for(int i=0;i<params[0];i++){ //cancel(true);されたか? if (isCancelled()) { //キャンセルされた場合は中断する Log.d("TAG_ASYNCTASK", "isCancelled"); AsyncTaskStopCount1=TimerCount1; text4.setText( "AsyncTask 中断タイミング = " + String.valueOf(AsyncTaskStopCount1)); //キャンセルされた場合、onPostExecuteは呼ばれない return String.valueOf(AsyncTaskStopCount1); } // 少し待つ try{Thread.sleep(100); } catch( InterruptedException e){ } AsyncTaskCount1++; //onProgressUpdateのvaluesに値を渡す//配列にできる publishProgress(AsyncTaskCount1,i+1); } AsyncTaskStopCount1=TimerCount1; //onPostExecuteのresultに渡す return String.valueOf(AsyncTaskStopCount1); } @Override protected void onProgressUpdate(Integer... values) { //Log.d("TAG_ASYNCTASK", "onProgressUpdate"); //valuesは、publishProgressの引数 //進捗状況が得られるので、 //プログレスバーなどにvaluesの値を入れる dialog.setProgress(values[1]); text2.setText( "AsyncTask Count= " + String.valueOf(values[0]) + " Progress = " + String.valueOf(values[1])); } @Override protected void onPostExecute(String result) { Log.d("TAG_ASYNCTASK", "onPostExecute"); //処理が終了した //resultは、doInBackgroundからの戻り値 text4.setText( "AsyncTask 終了タイミング = " + result); AsyncTaskRunCount1--; //ダイアログが出ていたら消す if(dialog != null && dialog.isShowing()) { dialog.dismiss(); } } @Override protected void onCancelled() { Log.d("TAG_ASYNCTASK", "onCancelled"); //cancel(true); が実行されたら呼び出される //何もしなければ、doInBackgroundで、タスクは実行を続けている } //「implements OnCancelListener」したことで実装 //ダイアログをキャンセルしたときに呼ばれる @Override public void onCancel(DialogInterface dialog) { // TODO 自動生成されたメソッド・スタブ Log.d("TAG_ASYNCTASK", "onCancel"); //AsyncTaskをキャンセルする cancel(true); } }

ログを見ると、onCancell、isCancelled、onCancelledの順番で呼ばれて、中断できたことになる。

onCancel
isCancelled
onCancelled

cancel(false)にすると、onCancelledが、isCancelledよりも先に呼ばれる場合もあるように見える?
場合によって使いわければいいということかも知れない。







AsyncTaskのクラスを作らずに記述する。


AsyncTaskTest1クラスを作らずに、次のようにも、書けます。
「implements OnCancelListener」は、不要です。
特に問題なければ、使い勝手によって見やすいコードを書けばいいと思います。


import android.content.DialogInterface.OnCancelListener; ............................ public void ToAsyncTask1(int count1){ new AsyncTask<Long, Integer, String>() { int AsyncTaskStartCount1=0; int AsyncTaskStopCount1=0; ProgressDialog dialog; Context context; @Override protected void onPreExecute() { //タスク開始 Log.d("TAG_ASYNCTASK", "onPreExecute"); context = MainActivity.this; AsyncTaskStartCount1=TimerCount1; AsyncTaskRunCount1++; text3.setText( "AsyncTask 起動タイミング = "+String.valueOf(AsyncTaskStartCount1)); //ダイアログを出す dialog = new ProgressDialog(context); dialog.setTitle("おまちください"); dialog.setMessage("実行中"); //dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);//くるくる //dialog.setIndeterminate(true);//進捗不確定モード dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);//プログレスバー dialog.setMax(100); dialog.setProgress(0); //ダイアログをキャンセルできるようにする dialog.setCancelable(true); dialog.setOnCancelListener(new OnCancelListener(){ @Override public void onCancel(DialogInterface dialog) { // TODO 自動生成されたメソッド・スタブ //ダイアログをキャンセルしたときに呼ばれる Log.d("TAG_ASYNCTASK", "onCancel"); //AsyncTaskをキャンセルする cancel(true); } }); dialog.show(); } @Override protected String doInBackground(Long... params) { //タスク実行 Log.d("TAG_ASYNCTASK", "doInBackground"); //paramsは、mAsyncTask1.executeの引数 for(int i=0;i<params[0];i++){ //cancel(true);されたか? if (isCancelled()) { //キャンセルされた場合は中断する Log.d("TAG_ASYNCTASK", "isCancelled"); AsyncTaskStopCount1=TimerCount1; text4.setText( "AsyncTask 中断タイミング = " + String.valueOf(AsyncTaskStopCount1)); //キャンセルされた場合、onPostExecuteは呼ばれない return String.valueOf(AsyncTaskStopCount1); } // 少し待つ try{Thread.sleep(100); } catch( InterruptedException e){ } AsyncTaskCount1++; //onProgressUpdateのvaluesに値を渡す//配列にできる publishProgress(AsyncTaskCount1,i+1); } AsyncTaskStopCount1=TimerCount1; //onPostExecuteのresultに渡す return String.valueOf(AsyncTaskStopCount1); } @Override protected void onProgressUpdate(Integer... values) { //Log.d("TAG_ASYNCTASK", "onProgressUpdate"); //valuesは、publishProgressの引数 //進捗状況が得られるので、 //プログレスバーなどにvaluesの値を入れる dialog.setProgress(values[1]); text2.setText( "AsyncTask Count= " + String.valueOf(values[0]) + " Progress = " + String.valueOf(values[1])); } @Override protected void onPostExecute(String result) { Log.d("TAG_ASYNCTASK", "onPostExecute"); //処理が終了した //resultは、doInBackgroundからの戻り値 text4.setText( "AsyncTask 終了タイミング = " + result); AsyncTaskRunCount1--; //ダイアログが出ていたら消す if(dialog != null && dialog.isShowing()) { dialog.dismiss(); } } @Override protected void onCancelled() { Log.d("TAG_ASYNCTASK", "onCancelled"); //cancel(true); が実行されたら呼び出される //何もしなければ、doInBackgroundで、タスクは実行を続けている } }.execute(100L); }






端末を回転させたときの対応。


端末を回転させると、Activityが破棄されて再生成されるので、いろいろとエラーが起きます。
まず、ダイアログが消えます。
処理が終わったとき、onPostExecuteで、ダイアログが出ていたら消すという処理をしていますが、
しかし、「if(dialog != null && dialog.isShowing())」では、ダイアログは出たままという判定をされて、
「dialog.dismiss();」でエラーになってしまいます。
ダイアログフラグメントにすれば大丈夫なのでしょうが、とりあえず、
処理中にダイアログが消えたら、もういっかいダイアログを出してみるという処理をすることにします。

ダイアログのインスタンスを、「static ProgressDialog dialog;」として、フィールドで設定。
onPause()で、ダイアログが出てたら消す。
onStart()で、AsyncTaskCount1の値が処理中だったら、ダイアログを出す。

あと、TextViewはstaticにしてみます。


これでとりあえず、大丈夫っぽいです。
問題が起きたら、また対策しましょう。


//端末を回転させたときに、ダイアログが消えるので対策する //MainActivityのフィールドで、ダイアログのインスタンスをstaticで作る static ProgressDialog dialog; .................... //AsyncTask内でインスタンスを作らない //ProgressDialog dialog; .................... @Override protected void onPause() { super.onPause(); //端末の回転対応 //ダイアログが出ていたら消す if(dialog != null && dialog.isShowing()) { dialog.dismiss(); } } @Override protected void onStart() { super.onStart(); //端末の回転対応 //処理中なら、ダイアログを出す if(AsyncTaskCount1%100!=0){ dialog.show(); } }



MainActivity.java

package com.example.test33; import java.util.Timer; import java.util.TimerTask; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.os.AsyncTask; import android.os.Bundle; import android.app.Activity; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; import android.content.DialogInterface.OnCancelListener; public class MainActivity extends Activity { static TextView text1; static TextView text2; static TextView text3; static TextView text4; Timer timer1 = new Timer(); static int TimerCount1 = 0; //private AsyncTask<Long, Integer, String> mAsyncTask1; static int AsyncTaskCount1=0; static int AsyncTaskRunCount1=0; //端末を回転させたときに、ダイアログが消えるので対策する //MainActivityのフィールドで、ダイアログのインスタンスをstaticで作る static ProgressDialog dialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout layout1 = new LinearLayout(this); setContentView(layout1); layout1.setOrientation(LinearLayout.VERTICAL); //縦に並ぶ text1 = new TextView(this); layout1.addView(text1); text2 = new TextView(this); layout1.addView(text2); text3 = new TextView(this); layout1.addView(text3); text4 = new TextView(this); layout1.addView(text4); Button button1 = new Button(this); button1.setText("AsyncTask"); layout1.addView(button1); button1.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { //AsyncTaskでカウントをはじめる ToAsyncTask1(TimerCount1); } }); //タイマータスクで一定時間おきにカウントする ToTimerTask1(); } @Override protected void onPause() { super.onPause(); //端末の回転対応 //ダイアログが出ていたら消す if(dialog != null && dialog.isShowing()) { dialog.dismiss(); } } @Override protected void onStart() { super.onStart(); //端末の回転対応 //処理中なら、ダイアログを出す if(AsyncTaskCount1%100!=0){ dialog.show(); } } private void ToTimerTask1(){ timer1.scheduleAtFixedRate(new TimerTask() { @Override public void run() { runOnUiThread(new Runnable() { public void run() { text1.setText("TimerCount1 / AsyncTaskRunCount1= " + String.valueOf(TimerCount1 ) + " / " + String.valueOf(AsyncTaskRunCount1)); } }); TimerCount1 += 1; } }, 0, 1000); } public void ToAsyncTask1(int count1){ new AsyncTask<Long, Integer, String>() { int AsyncTaskStartCount1=0; int AsyncTaskStopCount1=0; //端末を回転させたときに、ダイアログが消えるので対策する //AsyncTask内でインスタンスを作らない //ProgressDialog dialog; Context context; @Override protected void onPreExecute() { //タスク開始 Log.d("TAG_ASYNCTASK", "onPreExecute"); context = MainActivity.this; AsyncTaskStartCount1=TimerCount1; AsyncTaskRunCount1++; text3.setText( "AsyncTask 起動タイミング = "+String.valueOf(AsyncTaskStartCount1)); //ダイアログを出す dialog = new ProgressDialog(context); dialog.setTitle("おまちください"); dialog.setMessage("実行中"); //dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);//くるくる //dialog.setIndeterminate(true);//進捗不確定モード dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);//プログレスバー dialog.setMax(100); dialog.setProgress(0); //ダイアログをキャンセルできるようにする dialog.setCancelable(true); dialog.setOnCancelListener(new OnCancelListener(){ @Override public void onCancel(DialogInterface dialog) { // TODO 自動生成されたメソッド・スタブ //ダイアログをキャンセルしたときに呼ばれる Log.d("TAG_ASYNCTASK", "onCancel"); //AsyncTaskをキャンセルする cancel(true); } }); dialog.show(); } @Override protected String doInBackground(Long... params) { //タスク実行 Log.d("TAG_ASYNCTASK", "doInBackground"); //paramsは、mAsyncTask1.executeの引数 for(int i=0;i<params[0];i++){ //cancel(true);されたか? if (isCancelled()) { //キャンセルされた場合は中断する Log.d("TAG_ASYNCTASK", "isCancelled"); AsyncTaskStopCount1=TimerCount1; text4.setText( "AsyncTask 中断タイミング = " + String.valueOf(AsyncTaskStopCount1)); //キャンセルされた場合、onPostExecuteは呼ばれない return String.valueOf(AsyncTaskStopCount1); } // 少し待つ try{Thread.sleep(100); } catch( InterruptedException e){ } AsyncTaskCount1++; //onProgressUpdateのvaluesに値を渡す//配列にできる publishProgress(AsyncTaskCount1,i+1); } AsyncTaskStopCount1=TimerCount1; //onPostExecuteのresultに渡す return String.valueOf(AsyncTaskStopCount1); } @Override protected void onProgressUpdate(Integer... values) { //Log.d("TAG_ASYNCTASK", "onProgressUpdate"); //valuesは、publishProgressの引数 //進捗状況が得られるので、 //プログレスバーなどにvaluesの値を入れる dialog.setProgress(values[1]); text2.setText( "AsyncTask Count= " + String.valueOf(values[0]) + " Progress = " + String.valueOf(values[1])); } @Override protected void onPostExecute(String result) { Log.d("TAG_ASYNCTASK", "onPostExecute"); //処理が終了した //resultは、doInBackgroundからの戻り値 text4.setText( "AsyncTask 終了タイミング = " + result); AsyncTaskRunCount1--; //ダイアログが出ていたら消す if(dialog != null && dialog.isShowing()) { dialog.dismiss(); } } @Override protected void onCancelled() { Log.d("TAG_ASYNCTASK", "onCancelled"); //cancel(true); が実行されたら呼び出される //何もしなければ、doInBackgroundで、タスクは実行を続けている } }.execute(100L); } }






















戻る