【问题标题】:Progressdialog not dimissing进度对话框没有消失
【发布时间】:2011-09-12 10:03:12
【问题描述】:

我的代码尝试这样做:

  • onCreate 它创建一个异步任务 A 的实例
  • 我们调用 A 的 onPreExecute:showDialog
  • 在 doInBackground 中我们休眠了一段时间 SystemClock.sleep(1000)
  • onPostExecute 我们关闭对话框然后启动一个新的异步任务 B
  • 任务 B 的作用基本相同,打开一个等待然后关闭它的对话框。

现在,当您第一次打开应用程序时,事情应该会发生:您会看到两个进度对话框一个接一个地弹出,每个对话框持续一段时间。

但是,如果我在任何时候旋转屏幕,下次创建活动时,会创建进度对话框,但不会关闭。这使得无法使用 UI。如果我再次旋转屏幕,我会收到有关泄漏视图的错误消息(该对话框消失了)。另外,现在创建了新的对话框,并且不想消失(被解雇)。

这是我的代码:

public class MainActivity extends ListActivity {

    private static final int REFRESH_DIALOG = 100;
    private Resources resources;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        resources = getResources();
        setContentView(R.layout.listview);
        new CreationWork(this).execute();
        super.onCreate(savedInstanceState);
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
        case REFRESH_DIALOG:
            String message = resources.getString(R.string.refreshing);
            ProgressDialog refreshDialog = new ProgressDialog(this);
            refreshDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            refreshDialog.setMessage(message + "...");
            refreshDialog.setCancelable(false);
            return refreshDialog;
        default:
            return null;
        }
    }

    private static class CreationWork extends AsyncTask<Void, Void, DatabaseManager> {

        private MainActivity activity;

        public CreationWork(MainActivity activity) {
            this.activity = activity;
        }

        @Override
        protected void onPreExecute() {
            activity.showDialog(MainActivity.REFRESH_DIALOG);
            super.onPreExecute();
        }

        @Override
        protected DatabaseManager doInBackground(Void... params) {
            SystemClock.sleep(10000);
            return null;
        }

        @Override
        protected void onPostExecute(DatabaseManager result) {
            activity.dismissDialog(MainActivity.REFRESH_DIALOG);
            new RefreshWork(activity).execute();
            super.onPostExecute(result);
        }
    }

   static class RefreshWork extends AsyncTask<Void, Void, Cursor> {

        private MainActivity activity;

        public RefreshWork(MainActivity activity) {
            this.activity = activity;
        }

        @Override
        protected void onPreExecute() {
            activity.showDialog(MainActivity.REFRESH_DIALOG);
            super.onPreExecute();
        }

        @Override
        protected Cursor doInBackground(Void... params) {
            SystemClock.sleep(1000);
            return null;
        }

        @Override
        protected void onPostExecute(Cursor result) {
            activity.dismissDialog(MainActivity.REFRESH_DIALOG);
            super.onPostExecute(result);
        }
    }

}

一些调试信息:

在第二次轮换之前没有错误。这是有道理的,因为如果在第一次和第二次旋转之间没有关闭进度对话框,它们就会被有效地泄露。

当应用程序首次运行时,尽管两次调用 showDialog,onCreateDialog 仅被调用一次(我相信这是正常行为)。但是,在第一次轮换之后以及任何后续轮换时,每次运行都会调用两次 onCreateDalog。

【问题讨论】:

  • @nik 我在您的链接中找不到答案我不确定我什至要在那里寻找什么,也许您可​​以将您的建议作为答案发布,然后留下一个链接那个问题。谢谢
  • 为什么将 AsyncTasks 设为静态。我看不到那里的需要..如果那是您的真实(完整)代码。使它们成为非静态的。
  • 这与我的风格有关,除非我有充分的理由我总是将嵌套类设为静态,否则它们会更容易重构和移动。无论如何,我尝试了您的说法,但不幸的是,即使我使它们成为非静态的,问题仍然存在。
  • 是的,这几乎是骨架项目的完整代码。

标签: android android-asynctask performance


【解决方案1】:

尝试编写代码以在onPrepareDialog (int id, Dialog dialog, Bundle args) 方法上显示对话框。 根据showDialog 的文档, 第一次调用给定的 id 时,将使用相同的 id 调用 onCreateDialog(int, Bundle)

【讨论】:

  • 我在 API 级别 4,所以我不能这样做
【解决方案2】:

关闭活动的onDestroy() 中的对话框。否则在调用show() 之前检查对话框是否已经显示。看看这是否能解决问题。

更新

我认为满足您简单需求的最佳选择是ProgressDialog。你试过了吗?

ProgressDialog mProgDialog = ProgressDialog.show(YourActivity.this, "", 
                    "Loading. Please wait...", true);

onPostExecute中解散

mProgDialog.dismiss();

更新 2

我不确定这是否可行。在您的 Asynctasks 中覆盖 onCancelled 并在那里关闭您的进度对话框。因此,当方向更改并且如果通过调用取消取消异步任务时,对话框将被关闭。首先检查onCancelled是否在asynctask运行时activity被销毁时被调用。

【讨论】:

  • 我尝试在 onDestroy 上解除它们以堵塞泄漏,但没有任何效果。除了我需要在 onDestroy 之前摆脱对话框,以便用户可以与 UI 交互。
  • 在显示之前是否检查了 dilog 是否已经显示?
  • 您假设我直接与对话框交互。即 dialog.show()。但是请注意,我使用的是 showDialog(int)。 Android.App.Activity 的实现会检查(我假设)。仔细看看我发布的代码。
  • 是的,我已经使用了一段时间了,甚至它们也有自己的一系列问题,需要我花很多钱来管理它们。 onDialogCreate 旨在使这一点变得生动起来,所以我真的想确保在返回与对话框直接交互之前了解这里出了什么问题。
  • 更新 2:也试过了……不走运。线程并没有被取消(使用调试器)
猜你喜欢
  • 2017-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-27
相关资源
最近更新 更多