Progressdialog不解雇

时间:2011-09-12 10:03:12

标签: android android-asynctask performance

我的代码试图这样做:

  • onCreate it create a asnctask A
  • onPreExecute我们打电话:showDialog
  • 在doInBackground中我们睡了一会儿SystemClock.sleep(1000)
  • onPostExecute我们关闭对话框,然后启动一个新的异步任务B
  • 任务B通过打开一个等待然后关闭它的对话框来完成相同的操作。

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

但是,如果我随时旋转屏幕,则下次创建活动时,会创建进度对话框但不会被解除。这使得无法使用UI。如果我再次旋转屏幕,我会收到一个关于泄漏视图的错误消息(dint消失的对话框)。现在创建了新的对话框,也不想消失(被解雇)。

这里是我的代码:

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

}

一些调试信息:

没有错误直到第二次轮换。如果在第一次和第二次轮换之间没有取消进度对话框,这是有道理的,它们会被有效泄露。

当app首次运行时,尽管有两次调用showDialog,onCreateDialog只被调用一次(我相信这是正常行为)。但是在第一次旋转之后,对于任何后续旋转,onCreateDalog将在每次运行时被调用两次。

2 个答案:

答案 0 :(得分:0)

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

更新

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

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

解雇onPostExecute

mProgDialog.dismiss();

更新2

我不确定这是否有效。在Asynctasks中覆盖onCancelled并在那里关闭进度对话框。因此,当方向更改并且如果通过调用取消取消asynctasks,则对话框将被取消。首先检查在asynctask运行时销毁活动时是否调用onCancelled

答案 1 :(得分:0)

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