的onClick或onItemClick暂停时以&QUOT结果; IllegalStateException异常:无法执行与的onSaveInstanceState后QUOT这个动作;异常、动作、结果

2023-09-07 17:11:08 作者:愿时光待你安好

我有一个 TabActivity 它承载5倍 FragmentActivity 。其中一些包含按钮或列表,在其的onClick() onItemClick(),创建和推动新片段。

I have a TabActivity which hosts 5x FragmentActivity. Several of these contain buttons or lists that, in their onClick() or onItemClick(), create and push a new fragment.

在大多数情况下,这工作得很好,但是如果事情是有点反应迟钝,或测试人员做了愚蠢的(preSS-并按住按钮或列表项,使用不同的手指来切换标签,然后松开按钮/列表 - 100%可重复的),我得到好后的活动已经暂停,保存click事件。见日志片段:

For the most part, this works fine, but if things are being a bit unresponsive, or a tester does something silly (press-and-hold a button or list item, use a different finger to switch tabs, then release the button/list -- 100% reproducible), I get the click event well after the activity has been paused and saved. See log snippet:

10-30 17:05:16.258  3415  3415 D BKC DEBUG: More.onSaveInstanceState()
10-30 17:05:16.258  3415  3415 D BKC DEBUG: MoreFragment.onPause()
10-30 17:05:17.309  3415  3415 D BKC DEBUG: MoreFragment.onItemClick()

这篇文章和各种后计算器有关片段态损耗的问题,我没有看到一个很好的答案,如何解决这个问题。

After reading this article and various StackOverflow questions about fragment state loss, I don't see a good answer to how to fix this.

使用 commitAllowingStateLoss()(无条件)是可以隐藏真正的bug一种解决方法。我不知道该注销 OnClickListener OnItemClickListener 以s 的onSaveInstanceState 将100%prevent这一点,这是怎样的一个PITA做,对于每一个片段每个按钮。有人建议检查相关片段的 isAdded(),但我可以证实,不起作用。我可以设置在的onSaveInstanceState标志() onRestoreInstanceState(),然后检查的onClick()但同样,这只是一个杂牌组装电脑。编辑:哦,片段不具有 onRestoreInstanceState(),但我可以玩弄于 onResume)标志(或无论什么。 Using commitAllowingStateLoss() (unconditionally) is a workaround that could hide real bugs. I'm not sure that unregistering OnClickListeners and OnItemClickListeners in onSaveInstanceState would 100% prevent this, and it's kind of a PITA to do that for every button in every fragment. Someone suggested checking the relevant fragment's isAdded(), but I can confirm that doesn't work. I could set a flag in onSaveInstanceState() and onRestoreInstanceState() and check that in onClick(), but again, that's just a kludge. Oh, fragment doesn't have onRestoreInstanceState(), but I can twiddle the flag in onResume() or whatever.

有没有这一点,我缺少一个正确的修复,或者我应该只是我选择的杂牌去了?

Is there a correct fix for this that I'm missing, or should I just go with my kludge of choice?

推荐答案

想着它多一些,我相信 commitAllowingStateLoss()其实是在为正确答案这个案例。我们知道,我们是在的onClick() onItemClick()处理程序,因此,如果可能发生的状态丢失,知道这是因为这个洞,允许通过后的onSaveInstanceState()

After thinking about it some more, I believe that commitAllowingStateLoss() is in fact the right answer for this case. We know that we are in the onClick() or onItemClick() handler, so if state loss could occur, we know it's because of this hole that allows click events through after the onSaveInstanceState().

在我不经意的测试,新片段实际上将弹出当你回到到相应的标签,因为实际上什么也没有拆除。这是一个有点出人意料用户,但可能接受这种边缘情况。

In my casual testing, the new fragment will in fact pop up when you go back to the relevant tab, since nothing was actually torn down. That's a bit surprising to the user, but probably acceptable for this edge case.