41

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

本来我是用这个commit()方法的,但现在我打算不加选择地把这些改成commitAllowingStateLoss()片段活动

在不重新评估我使用片段的每个案例的情况下,是否有任何理由不不加选择地执行此操作?

4

5 回答 5

57

如果我理解正确,您的意思是:是否有任何理由在不重新评估我使用片段的每个案例的情况下不分青红皂白地这样做?

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

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

但是在替换commit为之前,您还应该考虑其他情况commitAllowingStateLoss

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

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

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

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

如果您确实决定使用,commitAllowingStateLoss那么您可以做一些事情来最大程度地减少所涉及的风险:例如,考虑在下次重新启动父活动时执行commit/ executePendingTransactions(我知道您不想这样做,但其他人可能会阅读内容)。

最后(再次以防其他人阅读此内容-这与您的情况无关)处理 an 的方法可能IllegalStateException比从 commit 移动到commitAllowStateLoss. 例如,您可以坚持提交并处理IllegalStateException. 或者,您可能遇到了Android 中的错误,并且可能有解决方法。

于 2013-07-08T12:56:47.223 回答
6
public abstract int commit ()

安排此事务的提交。提交不会立即发生;它将被安排在主线程上的工作,以便在该线程下一次准备好时完成。

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

public abstract int commitAllowingStateLoss ()

在 API 级别 11 中添加

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

FragmentActivity局限性

在 Honeycomb (3.0) 之前,活动的状态在暂停之前被保存。片段是大量的新状态,并且足够动态,以至于人们经常希望它们在暂停和停止之间切换。如果您在保存片段状态后尝试更改片段状态,这些类会引发异常,以避免意外丢失 UI 状态。然而,这在 Honeycomb 之前过于严格,在暂停之前会保存状态。为了解决这个问题,在 Honeycomb 之前的平台上运行时,如果您在状态保存和正在停止的活动之间更改片段,则不会引发异常。这意味着在某些情况下,如果活动从其上次保存的状态恢复,这可能是用户上次看到之前的快照。

因此,如果您不担心状态损失,我认为您的决定是可以的。我希望它可以帮助您做出决定。

于 2013-07-03T01:36:35.177 回答
4
try {
    transaction.commit();
} catch (IllegalStateException e) {
}
于 2017-05-25T15:50:04.913 回答
3

一个更好的主意是在 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.
}
于 2014-08-20T14:07:26.003 回答
1

您可以像这样覆盖下一个方法

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

它对我有用。

于 2016-12-24T22:30:41.477 回答