android - 在后台在 AsyncTask 中打开托管对话框时出现未定义的结果

标签 android multithreading

当用户(或其他应用程序,如电话应用程序)将我的应用程序推送到后台时,我遇到了一些问题。

我的应用程序执行以下操作:

  1. 用户可以输入一些应该被推送到服务器的信息。
  2. 当用户点击“发送”时,我会打开一个托管的 ProgressDialog 并启动一个执行服务器通信的 AsyncTask。
  3. 当服务器通信完成时,AsyncTask 向我的 Activity 报告,我在其中执行 dismissDialog()。
  4. 紧接在 dismissDialog() 之后,我将使用 showDialog() 显示另一个托管对话框,它会通知用户提交是否成功。

这一切都完美无缺;但是,当 AsyncTask 正在运行时碰巧有一个调用,我得到(看似随机的)这些结果之一:

  1. 持有托管对话框的 Activity 被完全关闭,当我回来时,会显示堆栈中的先前 View 。
  2. 持有托管对话框的 Activity 仍在屏幕上,但它是灰色的,没有显示对话框。解决此问题的唯一方法是旋转手机,此时它会正确显示“提交已发送”对话框,之后一切正常。

所有这一切都在没有任何警告消息的情况下发生,所以我完全不知道为什么 Android 会这样。

我知道解决这个问题的方法,那就是取消 AsyncTask(因此最后不会显示任何对话框)。然而,在这个用例中,要求应用程序必须尝试完成服务器事务,以便尽可能减少混淆(即用户想知道它是否真的已发送)。

有没有其他人遇到过这个问题并且知道解决办法?

最佳答案

我看到建议在 onRetainNonConfigurationInstance 中保留对异步任务的引用

What to do with AsyncTask in onPause()?

或者实现总线:

https://github.com/commonsguy/cwac-bus/tree

编辑:您的挑战的复杂性有两方面:

1) 在终止时保存和恢复你的应用程序状态,例如当有来电时

https://sites.google.com/site/jalcomputing/home/mac-osx-android-programming-tutorial/saving-instance-state

2) 以某种方式在 kill 时继续 asyncTask 而不是在暂停时取消它

https://sites.google.com/site/jalcomputing/home/mac-osx-android-programming-tutorial/asynch

这两个都是巨大的挑战,同时解决这两个问题会让我很头疼。事实上,我一想到它就头疼 :) 一个线索是你说对话框在方向改变时返回。这可能是因为使用对话框的标准架构,操作系统会在方向更改时为您处理保存和恢复对话框的状态。

[编辑] 参见 CommonsWare

@Override
public Object onRetainNonConfigurationInstance() {
    task.detach();
    return(task);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);      
    bar=(ProgressBar)findViewById(R.id.progress);   
    task=(RotationAwareTask)getLastNonConfigurationInstance();  
    if (task==null) {
        task=new RotationAwareTask(this);
        task.execute();
    }
    else {
        task.attach(this);
        updateProgress(task.getProgress());
        if (task.getProgress()>=100) {
            markAsDone();
        }
    }
}

其中任务是

的一个实例
static class RotationAwareTask extends AsyncTask<Void, Void, Void> {

我看不出为什么这不适用于所有类型的软杀戮,但在硬杀戮中,你会被杀。死了就死了:)

关于android - 在后台在 AsyncTask 中打开托管对话框时出现未定义的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6269278/

相关文章:

android - 获取订阅 android 的账单详细信息?

android - HTTP 发布请求 : Error 400, Firebase 主题消息

android - 如何在 android 的 Scrollview 中添加动态行 View ?

java - 如何在 Java EE 应用程序中使用多线程环境

java - 如何控制android平台上进程中运行的线程

multithreading - 一个 Tcl 线程如何在另一个线程中引发事件?

android - 下载管理器 COLUMN_LOCAL_FILENAME 已弃用

java - android studio 报错找不到包?和一些错误?

python - 如何在运行多线程计算然后绘制发出的结果时防止崩溃

java - Java 套接字中的并行处理无法正常工作