使用AsyncTask,ProgressDialog,AlertDialog和应用程序最小化/恢复时,UI会冻结

时间:2013-07-10 09:25:01

标签: android android-asynctask android-activity progressdialog android-alertdialog

首先,我的具体问题没有回答这个特别的问题。所以不要标记为重复,因为我在StackOverflow中找不到有效的响应。

考虑以下代码:

package xxx.MyActivity;

import com.xxx.R;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;

public class MyActivity extends Activity {

    private ProgressDialog progressDialog;
    private AlertDialog.Builder alertDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.my_activity);

        new MyTask().execute();
    }

    private class MyTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progressDialog = ProgressDialog.show(MyActivity.this,
                    getText(R.string.activity_dialog_generic_title),
                    getText(R.string.activity_reading), true);
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);

            progressDialog.dismiss();

            alertDialog = new AlertDialog.Builder(MyActivity.this);
            alertDialog.setCancelable(false);
            alertDialog.setMessage("dialog message");
            alertDialog.setPositiveButton("yes", null);
            alertDialog.setNegativeButton("no", null);
            alertDialog.show();
        }



        @Override
        protected Void doInBackground(Void... params) {

            int i = 0;
            while (++i < 10) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
            }

            return null;
        }
    }
}

如您所见,progressDialogalertDialog都是活动的变量。现在:

  1. 开始活动
  2. 等待进度显示
  3. 使用主页按钮“最小化”应用
  4. 等待10秒
  5. 返回应用
  6. 我没有警告对话框和UI被冻结(并且在显示对话框时显示为灰色,但屏幕上没有对话框)。后退按钮无效。

    修改

    在onPostExecute()中添加此代码:

    alertDialog.setOnCancelListener(new AlertDialog.OnCancelListener() {
        @Override
        public void onCancel(DialogInterface dialog) {
            finish();
        }
    });
    

    UI仍然看起来已经冻结,但屏幕上的触摸(对话框取消)将关闭活动(正如预期的那样:finish())。

    我还尝试对该行alertDialog.show();发表评论:没有冻结的用户界面,因此问题出在AlertDialog上。

1 个答案:

答案 0 :(得分:0)

我找到了解决这个问题的方法。

在Activity中使用变量showAlert,我可以知道,当Activity恢复时,是否先前显示过警告。如果为真我强制使用dialog.show()

没有按预期工作。请使用showAlert变量。

public class MyActivity extends Activity {

    private ProgressDialog progressDialog;
    private AlertDialog.Builder alertDialog;

    private volatile boolean showAlert;

    @Override
    protected void onResume() {
        super.onResume();

        try {
            if (alertDialog != null) {
                if (showAlert) {
                    alertDialog.show();
                }
            }
        } catch (Exception e) {
            finish();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.my_activity);

        new MyTask().execute();
    }

    private class MyTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            showAlert = false;

            progressDialog = ProgressDialog.show(MyActivity.this,
                    getText(R.string.activity_dialog_generic_title),
                    getText(R.string.activity_reading), true);
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);

            progressDialog.dismiss();

            alertDialog = new AlertDialog.Builder(MyActivity.this);
            alertDialog.setCancelable(false);
            alertDialog.setMessage("dialog message");
            alertDialog.setPositiveButton("yes", null);
            alertDialog.setNegativeButton("no", null);
            alertDialog.show();
            showAlert = true;
        }

        @Override
        protected Void doInBackground(Void... params) {

            int i = 0;
            while (++i < 10) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
            }
            return null;
        }

    }
}