2

AsyncTaskWithProgressAndroid では、タスクのバックグラウンド作業の実行中に進行状況ダイアログを表示するクラスを実装しました。

public abstract class AsyncTaskWithProgress<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {

private final FragmentActivity activity;
private final String action;
private final String title;
private final String message;
private final int icon;

public AsyncTaskWithProgress(FragmentActivity activity, String title, String message, int icon) {
    this.activity = activity;
    this.title = title;
    this.message = message;
    this.icon = icon;
    this.action = "" + hashCode();
}

@Override
protected final void onPreExecute() {
    DialogFragment fragment = ProgressDialogFragment.getInstance(action, title, message, icon);
    fragment.show(activity.getSupportFragmentManager(), "dialog");
    actualOnPreExecute();
}

protected void actualOnPreExecute() {
}

protected final void onPostExecute(Result result) {
    actualOnPostExecute(result);
    context.sendBroadcast(new Intent(action));
}

protected void actualOnPostExecute(Result result) {
}

}

Myはブロードキャストを受信するとすぐにダイアログをProgressDialogFagment登録しBroadcastReceiverてキャンセルします - 抜粋:

    public static Dialog getDialog(Activity activity, final String action, String title, String message, int icon,
        SerializableOnClickListener cancelListener) {
    final ProgressDialog dialog = new ProgressDialog(activity);
    dialog.setIndeterminate(true);
    dialog.setOwnerActivity(activity);
    dialog.setTitle(title);
    dialog.setMessage(message);
    if (cancelListener != null) {
        dialog.setButton(ProgressDialog.BUTTON_POSITIVE, "Cancel", cancelListener);
    }
    if (icon != MathUtils.NOT_AN_INT) {
        dialog.setIcon(icon);
    }

    BroadcastReceiver dismissReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            dialog.dismiss();
            context.unregisterReceiver(this);
            Log.d(getClass().getSimpleName(), "Dialog dismissed");
        }
    };
    context.registerReceiver(dismissReceiver, new IntentFilter(action));

    return dialog;
}

これは一般的に機能します。ただし、たまにダイアログがキャンセルされず、方向の変更が含まれているようです。

私の推測では、方向の変更中に、ダイアログのフラグメントが破棄され、再インスタンス化されると思います。AsyncTask が「Finished!」を送信した場合 フラグメントが破棄された後、再インスタンス化される前にブロードキャストする場合、フラグメントはブロードキャストに失敗するため、破棄されることはありません。

私の推測は正しいですか?これをより信頼性の高い方法で実装するにはどうすればよいですか?

4

1 に答える 1

0

フラグメントを使用しているため、代わりにsetRetainInstance()を使用して、構成の変更後も存続するフラグメントを作成することをお勧めします。そのフラグメントからブロードキャスト レシーバーを登録したり、進行状況を表示または非表示にしたりできます (フラグメントがユーザーに表示される必要はないことに注意してください)。

フラグメントなしで機能するもう 1 つの方法は、そのインテント用にスタンドアロンの BroadcastReceiver クラス (マニフェストに登録) を追加し、設定に値を保存して、ブロードキャストが受信されたことをアプリケーションに警告することです。

実際、スタンドアロンの BroadcastReceiver をスキップして、AsyncTaskWithProgress から設定に値を保存して、操作の現在の状態 (Status.LOADING、Status.LOADED、Status.CANCELLED など) を示すだけで、その値を onCreate( )。ただし、すでにフラグメントを使用しているため、 setRetainInstance() を使用するのが最善の方法だと思います。

于 2013-01-23T19:02:38.457 に答える