【问题标题】:UI freezes when using AsyncTask, ProgressDialog , AlertDialog and app minimization/restore使用 AsyncTask、ProgressDialog、AlertDialog 和应用程序最小化/恢复时 UI 冻结
【发布时间】:2013-07-10 09:25:01
【问题描述】:

首先,对于我的具体问题,这个特别的问题没有得到回应。所以不要标记为重复,因为我在 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. 返回应用

所以我没有警告对话框,并且 UI 被冻结(并且像显示对话框但屏幕上没有对话框时一样变灰)。后退按钮无效。

编辑:

在 onPostExecute() 中添加此代码:

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

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

我还尝试评论alertDialog.show();这一行:没有冻结的UI,所以问题出在AlertDialog

【问题讨论】:

  • 这段代码甚至无法编译。您不能在返回 Void 的方法上返回 true。当您可能已经编辑掉导致问题的原因时,可能很难诊断问题。无论如何,您可能正在寻找: private class MyTask extends AsyncTask {
  • 不管怎样,一旦更改为布尔值,您的代码就不会失败。它完全按照您的预期运行。
  • 我更正了代码。问题不在于返回 true。
  • 我用所有字符串而不是 Void 尝试了这段代码,它工作正常
  • @Seraphim 请尝试使用其他数据类型而不是 Void,因为您不能拥有 void 数据类型数组。

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


【解决方案1】:

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

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

    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多