2

在 Android 上,我实现了一个类AsyncTaskWithProgress,该类将在执行任务的后台工作时显示进度对话框:

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) {
}

}

我在收到广播后立即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 发送其“完成!” 在 Fragment 被销毁后重新实例化之前进行广播,Fragment 错过了广播,因此永远不会关闭。

我的猜测对吗?如何以更可靠的方式实现这一点?

4

1 回答 1

0

由于您使用的是片段,因此我建议您改用setRetainInstance()来制作一个在配置更改中持续存在的片段。您可以从该片段注册广播接收器,显示或隐藏进度等(请注意,片段不需要对用户可见。)

另一种不使用片段的方法是为该意图添加一个独立的 BroadcastReceiver 类(在您的清单中注册),并将一个值保存到首选项以提醒您的应用程序已收到广播。

事实上,您可以跳过独立的 BroadcastReceiver,只需将一个值保存到您的 AsyncTaskWithProgress 中的首选项中,该值指示操作的当前状态,例如 Status.LOADING、Status.LOADED、Status.CANCELLED 等,并在 onCreate( )。但是,我认为使用 setRetainInstance() 是最好的方法,因为您已经在使用片段。

于 2013-01-23T19:02:38.457 回答