旋转后,onCreate() Fragment在onCreate() FragmentActivity之前被调用。

59

我正在使用 FragmentActivity 和 Fragments。

当应用程序启动时:

FragmentActivity onCreate() <------
FragmentActivity onStart()
FragmentActivity onResume()
Fragment onAttach()
Fragment onCreate() <------
Fragment onCreateView()
Fragment onActivityCreated()
Fragment onStart()
Fragment onResume()

一切正常,FragmentActivity的onCreate()方法在Fragment的onCreate()方法之前调用。 当我旋转时:

Fragment onPause()
FragmentActivity onPause()
Fragment onStop()
FragmentActivity onStop()
Fragment onDestroyView()
Fragment onDestroy()
Fragment onDetach()
FragmentActivity onDestroy()
---
Fragment onAttach()
Fragment onCreate() <----------
FragmentActivity onCreate() <---------
Fragment onCreateView()
Fragment onActivityCreated()
Fragment onStart()
FragmentActivity onStart()
FragmentActivity onResume()
Fragment onResume()

为什么Fragment的onCreate()在FragmentActivity的onCreate()之前被调用?

在FragmentActivity的onCreate()中,我生成一些数据,而Fragment的onCreate()获取这些数据。因此,我不得不将我的代码从Fragment的onCreate()移动到Fragment的onCreateView()以确保我的数据已经被生成。

我正在使用FragmentStatePagerAdapter来保存Fragments,这可能是原因吗?


那么,你的解决方案是什么? - levi
@levi 在onActivityCreated()方法中填充你的视图数据。或者重新考虑你的架构,在大多数情况下,你不必从主活动获取数据。如果你有ListView/RecyclerView和动态数据,可以使用Loaders。这是我的最终解决方案,因为我在每个片段中都有List。你也可以使用消息总线库(EventBus、Otto等)来拥有更清晰的架构。 - AppiDevo
2个回答

66
在Fragment的生命周期中,在调用 onActivityCreated() 方法之前,不应该依赖于有效的Activity。

当片段的Activity已创建并实例化了此片段的视图层次结构时调用。可以在这些部件就位后进行最终初始化,例如检索视图或恢复状态。

确切的重建顺序原因我无法告诉你。允许每个组件以自己的节奏重新启动可能更有效率,而不是强制执行严格的顺序。例如,我喜欢我的LoaderManager尽早启动,布局内容则稍后再考虑。
(我喜欢好的图表。)

进入图像描述


由于 bug,仅在 onActivityCreated() 中初始化 Loders 是安全的,不能更早。https://code.google.com/p/android/issues/detail?id=183783 - AppiDevo
哇,我从未想到片段通过onAttach()与活动实例一起传递为“上下文”,而活动的onCreate()可能尚未被调用或完成!这帮助我理解了我的应用程序中的几个奇怪问题。 - rpattabi

32

在 Activity 的 onCreate() 方法中会恢复 Fragment。但是,值得注意的是,它们是在基础 Activity 类的 onCreate() 方法中恢复的。因此,如果你先调用 super.onCreate(),那么在 Fragments 被恢复后才会执行其余的onCreate() 方法。

因此,一种可行的解决方案是,在调用 super.onCreate() 之前,先恢复状态或计算 Fragment 需要的任何数据。

生命周期如下图:

ACTIVITY onCreate (pre-super)
FRAGMENT onAttach
ACTIVITY onCreate (post-super)

那么就像这样做:

@Override
public void onCreate( final Bundle savedInstanceState )
{
    Log.d( TAG, "ACTIVITY onCreate (pre-super)" );
    // Do your processing here
    super.onCreate( savedInstanceState ); // Fragments will be restored here
    Log.d( TAG, "ACTIVITY onCreate (post-super)" );
}

5
谢谢您的回复,我感激不尽。我为了解决这个问题搜索了两天,现在终于找到了答案。 - user3213851
2
值得一提的是,您可以在开发者选项中打开“不保留活动”以触发此行为,而无需进行配置更改。 - cascal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接