【问题标题】:Dialog dismiss on AsyncTask timeoutAsyncTask 超时时对话框关闭
【发布时间】:2014-11-05 05:41:58
【问题描述】:

我正在启动 AsyncTask 进行网络连接,我决定在 10 秒后超时之后应该取消任务以防万一网络问题

final aTask record = new aTask();
record.execute();
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
  @Override
  public void run() {
      if ( record.getStatus() == AsyncTask.Status.RUNNING ) {
          record.cancel(true);
      Toast.makeText(MainActivity.this, "Error in handling recording: connection timeout", Toast.LENGTH_SHORT).show();
      }
  }
}, 10000 );

我注意到 Spinner 对话框在异步任务取消后一直在运行。 我怎样才能忽略那个?

【问题讨论】:

  • 添加记录.dismiss();在运行方法上完成异步任务操作后
  • dismiss() 不是 AsyncTask 记录对象的方法
  • 你的代码是否抛出异常?
  • 方法不存在

标签: android android-asynctask dialog timeout dismiss


【解决方案1】:

更简单的方法是在 Handler 代码中添加 dialog.dismiss():

        final aTask record = new aTask();
        record.execute();
        Handler handler = new Handler();
        handler.postDelayed(new Runnable()
        {
          @Override
          public void run() {
              if ( record.getStatus() == AsyncTask.Status.RUNNING ) {
                  record.cancel(true);
                  dialog.dismiss(); <----------------- ADDED HERE
              Toast.makeText(MainActivity.this, "Error in handling recording: connection       timeout", Toast.LENGTH_SHORT).show();
              }
          }
        }, 10000 );

非常感谢大家的帮助

【讨论】:

  • 这是最好的一个,因为我在很多答案中磕磕绊绊 :)
【解决方案2】:

在全局范围内声明Dialog 类似

Dialog dlg;

在您的AsynTask 中的onPreExecute

dlg = new Dialog(MainActivity.this);
dlg.show();

doInBackground

if(this.isCancelled())
dlg.dismiss();

然后在您的AyncTask 中的onPostExecute 中执行此操作

 handler.postDelayed(new Runnable()
        {
          @Override
          public void run() {
              if ( this.getStatus() == AsyncTask.Status.RUNNING ) {
                  if(dlg.isShowing())
                  dlg.dismiss();
              Toast.makeText(MainActivity.this, "Error in handling recording: connection timeout", Toast.LENGTH_SHORT).show();
              }
          }
        }, 10000 );

或者,如果您只是想在AsynTask 完成其工作时关闭对话框,那么在onPostExecute 中只需使用dlg.dismiss()

信息

来自AsynTask.isCancelled()的文档

如果此任务在正常完成之前被取消,则返回 true。如果您在任务上调用 cancel(boolean),则应定期从 doInBackground(Object[]) 检查此方法返回的值,以尽快结束任务。

【讨论】:

  • 使用 if(this.isCancelled()) dlg.dismiss();在doInBackground()中,会检查一次吗?
  • 正如您在我编辑的答案的 Info 部分中看到的那样,如果您使用AsynTask.cancel(),那么您只需要为isCancelled() 操心。但是我建议不要要在任何地方使用cancel()isCancelled() 将仅在此任务在正常完成之前被取消且不会执行 onPostExecute 时返回 true。因此,如果任务因某种原因被取消,您需要手动关闭对话框.
  • 所以当doInBackground 运行时,isCancelled() 将被检查一次。但我认为如果你想要它关闭你的对话框,你不需要担心。
  • 处理程序代码应该在 onPostExecute 之外,否则它无法检查 AsyncTask 是否处于活动状态......并且 id doInBackground 我的连接代码应该在哪里?在 isCancelled() 检查之前还是之后?
【解决方案3】:

像这样为您的对话框提供全局参考。

Dialog d;

// 现在在你的 AsyncTask 中

Class MyTask extends AsyncTask{

  onPostExecute(){

     if(d!=null){
       d.dismiss(); // do this to dismiss once task finished
     }
  }

          @Override
    protected Object doInBackground(Object... params) {
        // TODO Auto-generated method stub
       // keep doing this 
        if(this.isCancelled()){
            d.dismiss();
        }

【讨论】:

  • 如果 AsyncTask 被取消,它是否有效,例如:record.cancel(true); ? onPostExecute() 可以识别已删除的任务吗?
  • 不,Android 4+ 操作系统版本不会调用它。为此,您可以在 doInbackground 中检查相同的内容,如果任务已取消,否则取消任务的逻辑,在该逻辑本身中,以与通过 onPostExecute 解除对话框相同的方式解除对话框。
  • 如何在 doInBackground if(this.isCancelled()) 中多次测试?
  • 无需多次测试,在从 doInBackground 返回之前添加我在代码中提到的检查。
【解决方案4】:

当您取消 Asynctask 时,她不会离开 doInBackground...

块引用 可以通过调用 cancel(boolean) 随时取消任务。调用此方法将导致对 isCancelled() 的后续调用返回 true。调用此方法后,将在 doInBackground(Object[]) 返回后调用 onCancelled(Object),而不是 onPostExecute(Object)。为了确保尽快取消任务,如果可能(例如在循环中),您应该始终定期从 doInBackground(Object[]) 检查 isCancelled() 的返回值。

偶尔检查一下 isCancelled():

 protected Object doInBackground(Object... x) {
    while (/* condition */) {
      // work...
      if (isCancelled()) break;
    }
    return null;
 }

【讨论】:

  • while 条件可能是什么?在 doInBackground 我试图建立一个网络连接,所以如果我使用 while(true) 它将打开许多连接,直到计时器停止......
  • while 条件就是一个例子。如果您需要取消网络连接,请使用超时。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-27
  • 1970-01-01
  • 2014-10-21
相关资源
最近更新 更多