4

抱歉,这是一篇相当长的帖子,让我先解释一下背景:

我已经阅读了很多关于这个主题的帖子(以及Alex 关于这个主题的优秀博文),一般的结论似乎不是在异步回调中执行片段事务(参见Dianne 的帖子),比如AsyncTask#onPostExecute().

但是,我有两种情况是必要的:

  1. 显示Activity登录Fragment,当用户按下登录按钮时,AsyncTask开始与服务器进行身份验证,然后当返回登录成功时,登录Fragment被主应用程序替换Fragment

  2. 显示Activity主应用程序片段,当用户触发一些需要登录的操作时,登录片段替换添加到后台堆栈的主片段。再次按下登录按钮时,AsyncTask通过服务器进行身份验证,然后当登录成功时,我们想要弹出回栈以Fragment向用户显示主要内容并让他们执行他们想要执行的操作。

案例 1 可以通过使用解决commitAllowingStateLoss,但案例 2 很棘手,因为在FragmentManager.

在任何情况下,这两种情况都需要在 期间对应用程序进入后台进行特殊处理AsyncTask#doInBackground(),从而导致onPostExecute()在应用程序处于后台时被调用。一种解决方案是使用 Fragment.isResumed 来保护替换片段或弹出回栈,然后通过再次登录或保存一些指示最近成功登录的标志来处理进程终止情况,并在应用恢复状态下替换/弹出登录片段(登录Fragment已恢复)到顶部FragmentManager)。或者允许状态丢失,并处理进程被杀死然后恢复的情况,检查最近登录并删除登录片段。

你会这样处理吗?只是为了处理一个非常常见的情况,感觉就像很多工作。

4

2 回答 2

6

最近的解决方法是调用FragmentActivity.onStateNotSaved()before popBackStack()

于 2017-05-09T16:49:07.980 回答
1

就像上面评论中提到的x90一样,最简单的解决方案是将您的片段拆分为单独的活动。这显然会避免异常,因为启动新活动不需要修改前一个活动的状态。像这样将片段交换进/出屏幕可能不是您想要做的......正如他们的名字所暗示的那样,Fragments 被设计为用作用户界面的“片段”,而不是像整个屏幕那样用户界面。(当然,我并不是说不允许你以这种方式使用Fragments ......我只是说这不是FragmentAPI 的设计目标)。

您也可以尝试在您的AsyncTask. 也就是说,如果活动开始进入后台,请立即取消任务。当AsyncTaskfinally 完成时,确保在执行片段事务等之前isCancelled()返回。false

于 2013-09-18T14:01:29.687 回答