これは私がいつも使っているものです。UI やリストボックスの更新などについては触れません。Task と ProgressDialog の処理だけです。
ProgressDialog のスタイル:
<resources>
<style name="MyProgressDialog" parent="@android:style/Theme.Dialog">
<item name="android:background">@android:color/transparent</item>
<item name="android:backgroundDimEnabled">false</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowFrame">@null</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
<item name="android:windowTitleStyle">@null</item>
</style>
</resources>
私の ProgressDialog クラス:
public class MyProgressDialog extends Dialog {
public MyProgressDialog(Context context) {
super(context, R.style.MyProgressDialog);
}
public static MyProgressDialog show(Context context, CharSequence title, CharSequence message) {
return show(context, title, message, false);
}
public static MyProgressDialog show(Context context, CharSequence title, CharSequence message, boolean indeterminate) {
return show(context, title, message, indeterminate, false, null);
}
public static MyProgressDialog show(Context context, CharSequence title, CharSequence message, boolean indeterminate, boolean cancelable) {
return show(context, title, message, indeterminate, cancelable, null);
}
public static MyProgressDialog show(Context context, CharSequence title, CharSequence message, boolean indeterminate, boolean cancelable, OnCancelListener onCancelListener) {
MyProgressDialog dialog = new MyProgressDialog(context);
dialog.setCancelable(cancelable);
dialog.setOnCancelListener(onCancelListener);
dialog.setTitle(title);
dialog.addContentView(new ProgressBar(context), new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
dialog.show();
return dialog;
}
}
今度は牛肉です。内部クラスとして AsyncTask を持つ ListView。AsyncTask は周囲の ListActivity (コンテキスト) への参照を保持し、ListActivity は AsyncTask への参照を保持します。ProgressDialog は、通常の開始時に AsyncTask に作成されます。ListActivity が停止し、AsyncTask がまだ実行中の場合、ダイアログは ListActivity から閉じられ、再起動後に再作成されます。
重要なことは、誰が何をしているかに注意することです。
public class MyListActivity extends ListActivity {
private class MyAsyncTask extends AsyncTask<Void, Integer, Boolean> {
/* package */ MyListActivity context;
/* package */ MyProgressDialog dialog;
public MyAsyncTask(MyListActivity context) {
super();
this.context = context;
}
@Override
protected Boolean doInBackground(final Void... voids) {
Boolean rc = false;
// Put your running task here
return rc;
}
@Override
protected void onPostExecute(final Boolean result) {
if (dialog != null) {
try {
dialog.dismiss();
} catch (Exception exception) {
}
dialog = null;
}
if (result) {
// Whatever you need to update in UI
}
context.task = null;
}
@Override
protected void onPreExecute () {
dialog = MyProgressDialog.show(context, null, null, true, false);
}
}
/* package */ MyAsyncTask task;
// Save AsyncTask if running, dismiss ProgressDialog if open
@Override
public Object onRetainNonConfigurationInstance() {
if (task != null) {
if (task.dialog != null) {
task.dialog.dismiss();
task.dialog = null;
}
}
return task;
}
@Override
public void onCreate(final Bundle bundle) {
// Usual start here
// Was task running?
task = (MyAsyncTask) getLastNonConfigurationInstance();
if (task != null) {
// Task was running, update context, restart ProgressDialog
task.context = this;
task.dialog = MyProgressDialog.show(this, null, null, true, false);
} else {
// Task was not running. Start from beginning
task = new MyAsyncTask(this);
task.execute();
}
}