Android AsyncTask和FragmentManager出现问题

Android AsyncTask和FragmentManager出现问题,android,android-asynctask,progressdialog,fragmentmanager,Android,Android Asynctask,Progressdialog,Fragmentmanager,我已经开发了一个应用程序,但是一个用户说该应用程序在某个特定部分对他们造成了崩溃,我怀疑是罪魁祸首的代码可以在下面找到,但要提供一些上下文。我有一个充当向导的片段管理器,在最后一个片段上有一个提交按钮,单击该按钮时,“处理”来自所有寻呼机片段的数据,然后重定向到确认片段,单击提交按钮后发生的所有这一切都在异步任务中完成。另外,如果有任何影响,我会在异步任务运行时运行一个进度对话框 //Called from Async Task's "onPostExecute()" private void

我已经开发了一个应用程序,但是一个用户说该应用程序在某个特定部分对他们造成了崩溃,我怀疑是罪魁祸首的代码可以在下面找到,但要提供一些上下文。我有一个充当向导的片段管理器,在最后一个片段上有一个提交按钮,单击该按钮时,“处理”来自所有寻呼机片段的数据,然后重定向到确认片段,单击提交按钮后发生的所有这一切都在异步任务中完成。另外,如果有任何影响,我会在异步任务运行时运行一个进度对话框

//Called from Async Task's "onPostExecute()"
private void callback()
{
    FragmentManager fragmentManager = getActivity()
            .getSupportFragmentManager();

    fragmentManager.popBackStack("fraud_report", FragmentManager.POP_BACK_STACK_INCLUSIVE);

    Fragment f =  new CompletedFragment();

    Bundle args = new Bundle();

    args.putString("id", reportToSubmit.getReferenceId());

    f.setArguments(args);

    fragmentManager.beginTransaction()
            .replace(R.id.content_frame, f, "completed").commit();

    fragmentManager.executePendingTransactions();


}

我有一个猜测,这可能是什么,特别是如果它很难复制。您的问题是,在异步回调之后,您正在执行一个
碎片事务
,在此期间可能会发生很多事情。因此,您无法保证您在活动生命周期中的位置。问题是碎片和状态丢失

例如,用户启动AsyncTask,然后结束活动,启动另一个活动,或者点击home按钮。所有这些都会将活动置于后台,并可能触发对
onSaveInstanceState
的调用调用onSaveInstanceState后无法提交片段事务。这是因为
FragmentManager
及其关联的所有状态已经捆绑在
onSaveInstanceState
中,因此如果活动被销毁并重新创建,您将丢失片段事务


至于解决这个问题,我希望我能给你一个好的建议。您可以查看
FragmentTransaction#commitAllowingStateLoss
,但只有在您确信潜在的故障不会对您的应用程序产生负面影响时,才应使用此选项。有关更多信息,请参阅上面的链接。

您提到有用户正在报告此问题。你的意思是你不能自己复制错误吗?堆栈跟踪会很有帮助。我们还没有做到。他们正在使用安卓4.3测试Note2。实际上,我们自己也在等待堆栈跟踪信息(我们已经在测试应用程序中设置了日志记录来记录这一信息)。不幸的是,到目前为止,我所要做的就是我上面提到的。不幸的是,在这一点上,我认为我们可能无法根据文章中的信息使用commitAllowingStateLoss。我们的应用程序中几乎每个片段都是静态的,不需要保留状态,但我将继续研究这个问题,直到我们得到更多关于用户错误的数据。Thank.TBH,我不得不多次使用commitAllowingStateLoss,因为唯一的解决方案是重新设计我们为异步任务所做的一切。如果用户在活动被销毁之前导航回该活动,则不会出现问题。只有当活动被销毁并且最后一个片段事务丢失时,这才是一个问题。当活动重新创建自身时,尝试看看是否有办法缓解这种情况。那么,如果所有这些都包含在单个活动中呢?我很好奇。在这一点上,担心活动破坏甚至是一种担忧吗?如果用户点击home按钮或其他什么,将您的活动放在后台,操作系统可以随时破坏活动以回收内存。当用户返回时,它将被重新创建(调用onCreate等)。在您的情况下,弹出后堆栈并添加CompletedFragment的片段事务将丢失。片段管理器将恢复到调用
onSaveInstanceState
时中的任何状态。请注意,这不会每次都发生,
onSaveInstanceState
必须在
回调之前调用。这是一场与操作系统的竞赛。因此,也许我试图解决错误的问题。流程如下:用户在每个查看页面屏幕上填写信息,移动到下一个,直到到达最后一个,然后点击submit->Async task Processs information(显示进度对话框),完成后,调用onPostExecute将用户移动到CompletedFragment。那么有没有更干净的方法呢?要处理用户输入(发送到服务器),然后在完成后显示新的成功屏幕?我还打算销毁视图寻呼机片段,这样如果用户想要填写并提交新向导,它就会被重置。