プロフィール


Live!Ads

カテゴリ

iPad (2)

スポンサー


検索(サイト内)

全タイトルを表示


最近の記事

最近のコメント

最近のトラックバック

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。



【--/--/-- --:--】 スポンサー広告| tb(-) cm(-)

[Android][Java]AyncTask+ProgressDialog のハマリポイント

Google さんが AsyncTask を使え! って言ったので、待ち時間の発生する処理は AsyncTask を使ってます。

よくある(というか必須?)パターンとして、待ってる間は、ProgressDialog で待ってる感を演出するわけですが、その際に少しハマったのでメモ。



ボタンを押す → プログレスダイアログを表示 → 時間のかかる処理を開始 → 処理終了 → Activity を閉じる
という処理として、下記のように書きました。
void onClick() {
final ProgressDialog dialog = null;
dialog = new ProgressDialog(this);
dialog.setMessage("処理中...");
dialog.setProgressStyle(
ProgressDialog.STYLE_SPINNER);
dialog.setCancelable(false);
dialog.show();

new AsyncTask() {
@Override
protected Exception doInBackground(
Void... params) {
/* 時間のかかる処理 */
return null;
}

@Override
protected void onPostExecute() {
dialog.dismiss();
}
}.execute();

finish(); // Activity を閉じる
}


これ、ソッコー落ちます(汗
よく見たら分かるんですが、変数 dialog は、onClick を抜けると(finish が実行されるとかな)破棄されてしまい、AyncTask の匿名クラス内の dialog.dismiss に到達した時には既に無効です。

ならば、ってことで普通なら dialog を AsyncTask の匿名クラス内にもっていくんでしょうけど、ひねくれ者なので、こんな風に書いてみました。
void onClick() {
final ProgressDialog dialog = null;
dialog = new ProgressDialog(this);
dialog.setMessage("処理中...");
dialog.setProgressStyle(
ProgressDialog.STYLE_SPINNER);
dialog.setCancelable(false);
dialog.show();

new AsyncTask() {
@Override
protected Exception doInBackground(
Void... params) {
/* 時間のかかる処理 */
return null;
}

@Override
protected void onPostExecute() {
dialog.dismiss();
finish(); // Activity を閉じる
}
}.execute();
}


dialog は、関数を抜けると破棄されてしまうのか、いや AsyncTask の匿名クラスで使われているとマークされていれば破棄されない、問題ないはずだと思ったのですが…、同じように(いや少し違った)エラーが発生してしまいました。

詳細は不明ですが、変数 dialog は、onClick のスコープを外れるとやはり破棄されてしまうようです。(onPostExecute に辿りつくまで、dialog が使われることを認識できないのかな?)

で、正しくは以下のコードですね。
void onClick() {
new AsyncTask() {
private ProgressDialog dialog = null;

protected void onPreExecute() {
dialog = new ProgressDialog(
HogeActivity.this);
dialog.setMessage("処理中...");
dialog.setProgressStyle(
ProgressDialog.STYLE_SPINNER);
dialog.setCancelable(false);
dialog.show();
};

@Override
protected Exception doInBackground(
Void... params) {
/* 時間のかかる処理 */
return null;
}

@Override
protected void onPostExecute() {
dialog.dismiss();
finish(); // Activity を閉じる
}
}.execute();
}

dialog は AsyncTask と共に生成~破棄されるので問題なく動作します。preXXX で生成して postXXX で破棄してるのでスッキリしてますね。

【教訓】
AsyncTask を呼び出す”だけ”のメソッドでは、なるべくローカル変数を使わないほうがよさそう。
スポンサーサイト
【2010/10/19 00:31】 Android| tb(0) cm(0)
タグ : Java
<<[Java]Java の enum に負けた話 | ホーム | [Twitter][API]Twitter API の位置検索のビミョーなところ>>
コメント
コメントの投稿

管理者にだけ表示を許可する

トラックバック
トラックバックURL
http://oku2006.blog43.fc2.com/tb.php/1609-1703d16d
| ホーム |
アクセスランキング
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。