commitAllowingStateLoss()在片段活动中

我的应用程序使用片段活动,它只是在肖像模式,没有办法旋转屏幕。

最初我使用的是commit()方法,但现在我打算不分青红皂地将这些改为commitAllowingStateLoss()来进行片段活动

如果不重新评估每个使用片段的个案,是否有任何理由不要不分青红皂白呢?

Solutions Collecting From Web of "commitAllowingStateLoss()在片段活动中"

如果我理解正确,你的意思是说:没有任何理由不要不加区别地做这个,而不重新评估每个使用片段的个案。

答案是肯定的 – 你不应该在没有仔细重新评估每个使用片段的个案的情况下这样做。

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

但在replacecommitAllowingStateLoss commit之前,还有其他一些情况需要考虑。

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

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

  3. Android可能会“杀死”一个片段,因为电话/标签资源不足(请参阅此答案 )。

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

如果你决定使用commitAllowingStateLoss那么你可以做的事情,以尽量减less所涉及的风险:例如考虑做一个commit / executePendingTransactions当父活动下一次重新启动(我知道你不想这样做,但其他人可能会读这 )。

最后(如果有人读这个 – 这与你的情况不相关),处理IllegalStateException比从提交到commitAllowStateLoss更安全。 例如你可以坚持提交并处理IllegalStateException 。 或者,您可能在Android中遇到了一个错误 ,可能会有解决方法。

 public abstract int commit () 

计划提交此事务。 提交不会立即发生; 它将被安排在主线程上工作,待下次线程准备完成。

事务只能在其包含活动保存其状态之前使用此方法提交。 如果在该点之后尝试提交,则会抛出exception。 这是因为如果活动需要从其状态恢复,则提交后的状态可能会丢失。 有关可能会丢失提交的情况,请参阅commitAllowingStateLoss()。

 public abstract int commitAllowingStateLoss () 

在API级别11中添加

像commit()一样,但是允许在一个activity的状态被保存之后执行commit。 这是很危险的,因为如果活动需要稍后从其状态恢复,那么提交可能会丢失,所以这应该只用于UI状态在用户意外改变的情况下。

FragmentActivity限制

在Honeycomb之前(3.0),一个活动的状态在暂停之前被保存。 碎片是一个新的国家的重要数量,并且足够dynamic,以至于人们经常希望他们在暂停和停止之间改变。 如果尝试在保存后更改片段状态,这些类将引发exception,以避免意外丢失UI状态。 但是,在Honeycomb之前,这个限制太多了,在这之前,状态是保存的。 为了解决这个问题,当在Honeycomb之前的平台上运行时,如果在状态保存和被停止的活动之间更改片段,则不会引发exception。 这意味着,在某些情况下,如果活动从最后一次保存的状态恢复,这可能是用户上次看到之前的快照。

所以,如果你对国家损失没有理解,我认为你的决定是可以的。 我希望它能帮助你做出决定。

一个更好的主意是在OnPostResumecallback中使用commit(),而不是不加select地使用commitAllowingStateLoss()。 以下博客提供了详细的解释http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html

 @Override protected void onPostResume() { super.onPostResume(); // Commit your transactions here. } 
 try { transaction.commit(); } catch (IllegalStateException e) { transaction.commitAllowingStateLoss(); } 

你可以重写下面的方法

 @Override public void supportFinishAfterTransition() { finish(); super.supportFinishAfterTransition(); } 

它为我工作。

只使用commitAllowingStateLoss()作为最后的手段。 调用commit()和commitAllowingStateLoss()之间的唯一区别是,如果发生状态丢失,后者不会抛出exception。 通常你不想使用这种方法,因为这意味着有可能发生状态损失。 当然,更好的解决scheme是编写应用程序,以确保在保存活动状态之前调用commit(),因为这会带来更好的用户体验。 除非无法避免状态丢失的可能性,否则不应使用commitAllowingStateLoss()。