0

我试图了解 Android 片段的内部行为。onDestroy()对, onDetach()和之间的确切区别有疑问

void onDestroy ()

当片段不再使用时调用。这被称为之后onStop()和之前onDetach().

void onDetach ()

当片段不再附加到其活动时调用。这在 onDestroy() 之后调用。

查询: 如果片段不再使用,意味着我们可以从 Activity 中删除该片段,对吗?

这种情况下为什么要先调用onDestroy()再调用onDetach(),我们只能用一种方法来表示“Fragment不再使用,可以移除activity”的状态

4

2 回答 2

0

如果您查看整个片段生命周期,那么

onAttach() onCreate()

是对应的

onDetach() onDestroy()

生命周期方法。所以为了不破坏设计一致性生命周期方法调用顺序如下

onAttach() 
onCreate()
onDestroy()
onDetach() 

现在让我们继续您的查询

查询:如果片段不再使用,意味着我们可以从 Activity 中删除该片段,对吗?

这种情况下为什么要先调用onDestroy()再调用onDetach(),我们只能用一种方法来表示“Fragment不再使用,可以移除activity”的状态

Android 总是试图维护它的对应物。回答您的查询为什么 onAttached 首先给出您的查询答案

片段被设计为独立于活动。onAttach() 提供了一个接口,用于在初始化片段之前参考片段确定包含活动的状态/类型/(对片段重要的其他细节)。

于 2018-09-28T07:47:46.443 回答
0

onDestroy()onDestroy()调用以对片段的状态进行最终清理,但不保证会被 Android 平台调用。 (在片段不再使用时调用,在 onStop 之后和 onDetach() 之前)

onDetach()onDetach()在 之后调用onDestroy(),以通知片段已与其托管活动解除关联。(当片段不再附加到其活动时调用)

参考android-fragment-lifecycleonDestroyonDetach

看一下 Fragment 类(第 1564 行),如果 f.mRetaining 为 false,则首先调用 performDestroy:

if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f);
if (!f.mRetaining) {

        //performDestroy is called first if f.mRetaining is false, else not
        f.performDestroy();
        dispatchOnFragmentDestroyed(f, false);
} else {
        f.mState = Fragment.INITIALIZING;
}
//then performDetach
f.performDetach();
dispatchOnFragmentDetached(f, false);
if (!keepActive) {
        if (!f.mRetaining) {
            makeInactive(f);
        } else {
            f.mHost = null;
            f.mParentFragment = null;
            f.mFragmentManager = null;
        }
}

这里是 performDestroy 和 performDetach 的代码:

void performDestroy() {
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
        if (mChildFragmentManager != null) {
            mChildFragmentManager.dispatchDestroy();
        }
        mState = INITIALIZING;
        mCalled = false;
        mIsCreated = false;
        onDestroy();
        if (!mCalled) {
            throw new SuperNotCalledException("Fragment " + this
                    + " did not call through to super.onDestroy()");
        }
        mChildFragmentManager = null;
    }

    void performDetach() {
        mCalled = false;
        onDetach();
        mLayoutInflater = null;
        if (!mCalled) {
            throw new SuperNotCalledException("Fragment " + this
                    + " did not call through to super.onDetach()");
        }

        // Destroy the child FragmentManager if we still have it here.
        // We won't unless we're retaining our instance and if we do,
        // our child FragmentManager instance state will have already been saved.
        if (mChildFragmentManager != null) {
            if (!mRetaining) {
                throw new IllegalStateException("Child FragmentManager of " + this + " was not "
                        + " destroyed and this fragment is not retaining instance");
            }
            mChildFragmentManager.dispatchDestroy();
            mChildFragmentManager = null;
        }
    }
于 2018-09-28T07:09:52.767 回答