【问题标题】:When Fragment onActivityCreated called当 Fragment onActivityCreated 被调用时
【发布时间】:2019-11-06 20:09:42
【问题描述】:

在Google架构组件和LiveData之前我没有关注onActivityCreated()回调。 我在 SOF 和文档中都读到了这个,但我仍然无法理解这种行为。

来自 SOF 的一个答案:

顾名思义,这是在 Activity 的 onCreate() 完成后调用的 完成。

  • onActivityCreated()调用onActivityCreated()不调用在哪些情况下?

  • 有没有可能onCreateView() 被调用但onActivityCreated() 未被调用?

onActivityCreated() 中附加LiveData 观察者是常见的做法,所以我猜onActivityCreated()onCreateView() 之间存在显着差异?

尽管从官方 Android 文档中查看图表,onActivityCreated()onCreateView() 之后被称为总是(就执行而言,而不是顺序而言)并且没有区别?

这里有些混乱。

更新: onActivityCreated() 已弃用。

【问题讨论】:

  • 如果您将片段添加到Activity 然后重新创建它(例如在方向更改期间)FragmentManager 将在活动onCreate 调用期间重新创建您的片段。
  • 它们永远不会被重新排序,因此onActivityCreated 将始终在onViewCreated 之后调用。但是,对于无头片段(从 onCreateView 返回 null)并非如此,在这种情况下,根本不会调用 onViewCreated,但会调用 onActivityCreated
  • 我知道它们永远不会被重新排序,但onActivityCreated 总是在onViewCreated 之后执行(非无头片段)

标签: android android-fragments android-lifecycle


【解决方案1】:

编辑: 根据 Twitter 上的 Ian Lake(参见 https://twitter.com/ianhlake/status/1193964829519667202),FragmentActivity 尝试在 onStart 中发送 onActivityCreated 的事实无关紧要,因为无论发生什么,FragmentManager 在从onCreateonStart 时都会调度它。

            case Fragment.CREATED:
                // We want to unconditionally run this anytime we do a moveToState that
                // moves the Fragment above INITIALIZING, including cases such as when
                // we move from CREATED => CREATED as part of the case fall through above.
                if (newState > Fragment.INITIALIZING) {
                    fragmentStateManager.ensureInflatedView();
                }
                if (newState > Fragment.CREATED) {
                    fragmentStateManager.createView(mContainer);
                    fragmentStateManager.activityCreated(); // <--
                    fragmentStateManager.restoreViewState();

所以我下面说的其实是错的。

显然在 Fragment 中使用onActivityCreated 等同于使用onViewCreated

但这也意味着你不应该依赖onActivityCreated 来知道你的Activity 是否被实际创建,因为它被调用的次数比实际创建Activity 的时间要多。

片段令人困惑。



原始答案:

是否有可能 onCreateView() 被调用但 onActivityCreated() 没有被调用?

更新:不,这是不可能的。

原文:是的,在FragmentPagerAdapter 中,他们使用FragmentTransaction.detach / FragmentTransaction.attach,这会导致视图被销毁,但片段仍然存在(停止,但未销毁)。

在这种情况下,.attach() 运行 onCreateView,但不是 onActivityCreated

通常的做法是在 onActivityCreated() 中附加 LiveData 观察者,所以我猜 onActivityCreated() 和 onCreateView() 之间存在显着差异?

更新:没关系,尽管onViewCreated 仍然更清晰

原文:这实际上是一种不好的做法,应该在onViewCreated 中完成,提供getViewLifecycleOwner() 作为生命周期所有者。

虽然从官方 Android 文档中查看图表似乎总是在 onCreateView() 之后调用 onActivityCreated() 并且没有差异?

更新:尽管FragmentActivity 只尝试调度一次,但所有 Fragment 始终通过 onActivityCreated,因为这正是 FragmentManager 的工作方式。

原文:它并不总是在onCreateView之后调用,实际上,它更像是所谓的“在onStart之前,但只有一次”。

/**
 * Dispatch onStart() to all fragments.
 */
@Override
protected void onStart() {
    super.onStart();

    mStopped = false;

    if (!mCreated) {
        mCreated = true;
        mFragments.dispatchActivityCreated(); // <---
    }

    mFragments.noteStateNotSaved();
    mFragments.execPendingActions();

    // NOTE: HC onStart goes here.

    mFragments.dispatchStart();
}

更新: 但显然这对 FragmentManager 来说并不重要,因为无论哪种方式,它都会以CREATED -&gt; ACTIVITY_CREATED -&gt; STARTED 运行。

【讨论】:

  • @PavelPoley 状态更新:显然 Fragments 比我声称的更古怪,你应该检查这个答案的新状态。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-06
  • 2013-06-16
  • 2019-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多