片段活动中的commitAllowingStateLoss()

时间:2013-06-19 06:52:08

标签: android fragment android-fragmentactivity

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

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

有没有理由不重新评估我使用片段的每个案例时不加区别地做这件事?

5 个答案:

答案 0 :(得分:53)

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

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

当然,通过阻止因配置更改(屏幕旋转)而重新启动,您已经消除了一个关键问题区域:即用户可以在调用onSaveInstanceState之后但在commitAllowingStateLoss之前旋转屏幕}。在这种情况下,UI的片段或部分可能会丢失。有关此问题的非正式讨论,请参阅此post

但在将commit替换为commitAllowingStateLoss之前,您还应考虑其他一些情况。

  1. 基本上,onSaveInstanceState和commitAllowingStateLoss之间的任何UI更新: Android: IllegalStateException - When is it thrown?

  2. 如果您有任何无头片段更新了您的活动用户界面,那么他们的某些更新可能会丢失(请参阅此article)。

  3. Android可能会“杀死”某个片段,因为手机/标签资源不足(请参阅此answer)。

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

    如果您决定使用commitAllowingStateLoss,那么您可以采取措施将风险降至最低:例如考虑在下次重新启动父活动时执行commit / executePendingTransactions(我知道您不想这样做,但其他人可能会阅读this)。

    最后(再次以防其他人阅读此内容 - 这与您的情况无关)可能有更安全的方法来处理IllegalStateException而不是从提交转移到commitAllowStateLoss。例如,您可以坚持使用提交并处理IllegalStateException。或者,您可能在Android中遇到bug,但可能有解决方法。

答案 1 :(得分:5)

public abstract int commit ()

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

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

public abstract int commitAllowingStateLoss ()

在API级别11中添加

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

FragmentActivity限制

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

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

答案 2 :(得分:3)

try {
    transaction.commit();
} catch (IllegalStateException e) {
    transaction.commitAllowingStateLoss();
}

答案 3 :(得分:2)

更好的想法是在OnPostResume回调中使用commit()而不是不加区分地使用commitAllowingStateLoss()。以下博客提供了详细的解释 http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html

@Override
protected void onPostResume() {
    super.onPostResume();
    // Commit your transactions here.
}

答案 4 :(得分:0)

您可以覆盖下一个方法

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

它对我有用。