片段活动中的commitAllowingStateLoss()

CQM*_*CQM 39 android fragment android-fragmentactivity

我的应用程序使用片段活动,它只处于纵向模式,无法旋转屏幕.

最初我使用的是这种commit()方法,但现在我计划不加区别地将这些更改commitAllowingStateLoss()为片段活动

如果不重新评估我使用片段的每个个案,是否有任何理由不得不加区分?

Ian*_*anB 55

如果我理解正确你的意思是:有没有理由不重新评估我使用片段的每个个案?

答案是肯定的 - 如果不仔细重新评估使用片段的每个案例,就不应该这样做.

当然,通过防止由于配置更改(屏幕旋转)导致的重新启动,您已经消除了一个关键问题区域:即,用户可以在呼叫之后旋转屏幕onSaveInstanceState但是在之后commitAllowingStateLoss.在这种情况下,UI的片段或部分可能会丢失.有关此问题的非正式讨论,请参阅此文章.

但也有你更换前应考虑其他情形commitcommitAllowingStateLoss.

  1. 基本上,onSaveInstanceState和commitAllowingStateLoss之间的任何UI更新: Android:IllegalStateException - 何时抛出?

  2. 如果您有任何无头片段更新您的活动的UI,那么他们的一些更新可能会丢失(请参阅此文章).

  3. Android可能会"杀死"一个片段,因为手机/标签的资源不足(请参阅此答案).

当然,如果防止了屏幕旋转,则onSaveInstanceState可能不会被调用,在这种情况下,增加了丢失更新的机会窗口.

如果您决定使用commitAllowingStateLoss那么您可以采取哪些措施来最大限度地降低所涉及的风险:例如,考虑在下次重新启动父活动时执行commit/ executePendingTransactions(我知道您不想这样做,但其他人可能会阅读此内容).

最后(再次以防其他人读到这个 ​​- 这与你的情况无关),可能有更安全的方法来处理,而IllegalStateException不是从提交转移到commitAllowStateLoss.例如,你可以坚持提交和处理IllegalStateException.或者,您可能遇到了Android中的错误,可能有解决方法.

  • 有关此主题,请参阅我的[**博客文章**](http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html)以获取更多信息. (14认同)

Dio*_*nto 6

public abstract int commit ()
Run Code Online (Sandbox Code Playgroud)

安排提交此交易.提交不会立即发生; 它将被安排为主线程上的工作,以便在下一次线程准备就绪时完成.

事务只能在其包含活动保存其状态之前使用此方法提交.如果在该点之后尝试提交,则将引发异常.这是因为如果活动需要从其状态恢复,则提交后的状态可能会丢失.请参阅commitAllowingStateLoss()以了解可能丢失提交的情况.

public abstract int commitAllowingStateLoss ()
Run Code Online (Sandbox Code Playgroud)

在API级别11中添加

与commit()类似,但允许在保存活动状态后执行提交.这很危险,因为如果活动需要稍后从其状态恢复,则提交可能会丢失,因此这应该仅用于UI状态可以在用户上意外更改的情况.

FragmentActivity 限制

在Honeycomb(3.0)之前,活动的状态在暂停之前被保存.碎片是一个重要的新状态,并且足够动态,人们通常希望它们在暂停和停止之间切换.如果您尝试在保存后更改片段状态,则这些类会抛出异常,以避免意外丢失UI状态.然而,在蜂窝状态之前,这种限制性太强,在暂停之前状态会被保存.为了解决这个问题,当在Honeycomb之前的平台上运行时,如果在状态保存和正在停止的活动之间更改片段,则不会抛出异常.这意味着在某些情况下,如果活动从上次保存的状态恢复,则可能是用户上次查看之前的快照.

所以,如果你没有被国家损失所掩盖,我认为你的决定是可以的.我希望它能帮助你做出决定.