35

我有一个AsyncTask,它在工作时显示一个 progressDialog(它从doInBackground 中调用 runOnUiThread显示进度对话框)。

虽然它正在运行,但我想允许使用后退按钮取消操作;其他人遇到了这个问题:BACK Button is not working , while progressDialog is running

由于什么原因我无法回复该线程,因此不得不开始另一个?!(另一天的另一个问题)

我和 Sandy 有同样的想法,但是在显示progressDialog时从未调用过这段代码,这是为什么呢?我已经在我的主要活动类中实现了它,progressDialog是否暂时将前景焦点从我的类中移开?

4

9 回答 9

46

首先,您应该从 中显示您的对话框OnPreExecute,将其隐藏在 中OnPostExecute,并在必要时通过发布进度对其进行修改。(见这里

现在回答您的问题:ProgressDialog.show()可以将 aOnCancelListener作为参数。您应该提供一个调用cancel()进度对话框实例的方法。

例子:

    @Override
    protected void onPreExecute(){
        _progressDialog = ProgressDialog.show(
                YourActivity.this,
                "Title",
                "Message",
                true,
                true,
                new DialogInterface.OnCancelListener(){
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        YourTask.this.cancel(true);
                        finish();
                    }
                }
        );
    }

_progressDialogProgressDialog成员在哪里YourTask

此类在 API 级别 26 中已弃用。ProgressDialog 是一个模式对话框,可防止用户与应用程序交互。您应该使用 ProgressBar 之类的进度指示器,而不是使用此类,它可以嵌入到应用程序的 UI 中。或者,您可以使用通知来通知用户任务的进度。关联

于 2011-03-10T01:04:08.010 回答
17

这可以通过以下代码片段来实现:

progress.setCancelable(true);
progress.setCanceledOnTouchOutside(false);

进度是 ProgressDialog 对象...

这将启用后退按钮以关闭对话框,但阻止任何触摸输入来执行此操作...

于 2014-11-03T03:54:43.567 回答
14

好吧,我有同样的问题。对我有用的最简单的方法是使用progressDialog.setCancelable(true).. 这声明对话框是否可以通过按返回键来取消.. 试试看,让我知道它是否适合你。祝你好运

于 2011-11-01T03:03:02.820 回答
9

我刚刚找到了一个完美而简单的解决方案来解决这个问题。有一种方法ProgressDialog可以设置 KeyListener。

progressDialog.setOnKeyListener(new OnKeyListener() {
    @Override
    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
        if(keyCode==KeyEvent.KEYCODE_BACK && !event.isCanceled()) {
            if(progressDialog.isShowing()) {
                //your logic here for back button pressed event
            } 
            return true;
        }
        return false;
    }
});

它与setCancelable(false). 我也在检查event.isCanceled(),因为没有它我得到了两个事件。我已经在有和没有硬件密钥的棒棒糖设备上对此进行了测试。

于 2015-07-31T03:55:57.500 回答
5

将后退按钮视为取消是不正确的方法。
当用户在对话框之外触摸屏幕时也会发生取消。你想区分这两个动作,不是吗?

正确的方法是扩展 ProgressDialog 类并覆盖 onBackPressed 方法。

private class SubProgressDialog extends ProgressDialog {
    public SubProgressDialog(Context context) {
        super(context);
    }
    @Override
    public void onBackPressed() {
        /** dismiss the progress bar and clean up here **/
    }
}


public void displayProgressBar(){
    progressBar = new SubProgressDialog(this);
    progressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    progressBar.setCancelable(false);
    progressBar.setMessage(getString(R.string.authorizing));        
    progressBar.show();   
    new Thread(new Runnable() {
      public void run() {
      }
       }).start();     

}

注意 setCancelable(false),再次强调后退按钮不同于简单的取消。
这也将有效地忽略来自用户的任何其他触摸输入。

于 2013-02-27T23:27:55.380 回答
3

这是我的解决方案。PD 问题仅在应用程序退出后退按钮时发生(通常是当用户重复按下它时,并且只有有时(不是所有时间)当应用程序已经销毁时才会调用 PD。由于某种原因关闭 PDonDestroy不起作用并且当我尝试过时,每次按下后退按钮都会关闭应用程序,尽管canGoBack()设置为 true。相反,我关闭了goBack首先导致碰撞的事件的 PD,并且我在之前就这样做了finish()。如果应用程序在 goBack 上退出通常首先没有问题。

顺便说一句,“差异”旨在让用户通过快速双击(两次单击之间 400 毫秒)退出应用程序,而不是从一个页面返回到另一个页面。

希望它可以帮助某人...

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (event.getAction() == KeyEvent.ACTION_DOWN) {
        switch (keyCode) {
        case KeyEvent.KEYCODE_BACK:
            difference = System.currentTimeMillis() - startTime;
            if (wView.canGoBack() && difference > 400) {
                wView.goBack();
            } else {
                dismissProgressDialog();
                finish();
            }
            startTime = System.currentTimeMillis();
            return true;
        }
    }
    return super.onKeyDown(keyCode, event);
}


private void dismissProgressDialog() {
   if (progressDialog != null && progressDialog.isShowing()) {
        progressDialog.dismiss();
   }
}
于 2014-11-20T16:50:34.403 回答
2

javano... 我使用标准技术 asyncTask 和 ProgressDialog 测试了您的场景。在我的测试中,当显示progressDialog 并且我回击时,progressDialog 被关闭并且后台线程继续运行。我不知道你为什么需要调用 runOnUiThread。

所以:

在 onPreExecute 中显示 progressDialog 将长时间运行的任务放在 doInBackground 中,在 onPostExecute 中关闭 progressDialog 将输入参数传递给长时间运行的任务,如下所示:

new MyAsynch().execute(password,inString);

cancel() onPause 中的 asynchTask 和 progressDialog

protected void onPause() {
    super.onPause();
    if (asynch != null) {asynch.cancel(true);}
    if (progress != null){progress.cancel();}
}

日航

这里有一些代码。

于 2011-03-10T06:10:12.010 回答
1

它非常简单,只需复制以下代码并粘贴到异步任务中即可。

ProgressDialog 对话框;

@Override
protected void onPreExecute() {

    dialog = new ProgressDialog(MainActivity.this) {
        @Override
        public void onBackPressed() {
            dialog.cancel();
            dialog.dismiss();
        }
    };
    // dialog.setTitle("file is..");//its optional If u want set title in progress
    // bar
    dialog.setMessage("Loading file....");
    dialog.setCancelable(false);

    dialog.show();

}
于 2015-04-18T05:43:33.510 回答
0

请按照此操作,它仅显示异步取消按钮,单击取消按钮将调用完成

protected void onPreExecute() {


        dialogx.setMessage("Loading... Please Wait...");
        dialogx.setCancelable(false);
        dialogx.setButton(DialogInterface.BUTTON_NEGATIVE,
                "Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

                dialogx.dismiss();
                GetDataTask.this.cancel(true);
                finish();
            }
        });
        dialogx.show();


    }
于 2014-12-31T11:10:02.010 回答