弹出后栈时,片段是否会被破坏?

时间:2014-10-26 18:19:14

标签: java android android-fragments

无法找到这方面的直接答案,所以我会在这里问。

如果我有一个以附加片段A开始的活动,然后当按下A上的按钮时,它将片段A替换为片段B.A被添加到后栈。如果按下后退按钮,它将从B返回到A,但我想知道片段B是否被破坏了?因为从技术上讲,活动不是这样,我需要明确删除片段B,即使后面的堆栈是弹出的吗?

感谢您阅读

3 个答案:

答案 0 :(得分:5)

根据Android API,它没有被破坏,它被停止了。 http://developer.android.com/guide/components/fragments.html#Lifecycle

处理片段生命周期

停止
片段不可见。主机活动已停止或片段已从活动中删除但已添加到后台堆栈。已停止的片段仍处于活动状态(系统会保留所有状态和成员信息)。但是,它不再对用户可见,并且如果活动被杀死将被杀死。

答案 1 :(得分:0)

不,它没有被破坏,它停止了

它的状态是这样的 (在互动时)     1.)onAttach(Activity)在片段与其活动相关联时调用。     2.)onCreate(Bundle)调用来做片段的初始创建。     3.)onCreateView(LayoutInflater,ViewGroup,Bundle)     4.)onActivityCreated(Bundle)     5.)onViewStateRestored(Bundle)     6.)onStart()     7.)onResume()

虽然没有互动     1.)onPause()     2.)onStop()
    3.)onDestroyView()     4.)onDestroy()     5.)onDetach()

答案 2 :(得分:0)

片段管理器的一个后台堆栈意味着您计划的一个片段操作。 FragmentManagerImpl持有一个字段“mBackStack”来处理这样的事情。

根据Android API:

“...然而,在调用commit()之前,您可能需要调用addToBackStack(),以便将事务添加到片段事务的后台堆栈。此后台堆栈由活动管理并允许用户返回上一个片段状态,按“返回”按钮。“

让我们看看Activity.onBackPressed()中发生了什么:

/**
 * Called when the activity has detected the user's press of the back
 * key.  The default implementation simply finishes the current activity,
 * but you can override this to do whatever you want.
 */
public void onBackPressed() {
    if (mActionBar != null && mActionBar.collapseActionView()) {
        return;
    }

    FragmentManager fragmentManager = mFragments.getFragmentManager();

    if (fragmentManager.isStateSaved() || !fragmentManager.popBackStackImmediate()) {
        finishAfterTransition();
    }
}

如果活动是FragmentActivity的实例,则持有FragmentManagerImpl实例的字段“final FragmentController mFragments”将调用popBackStackImmediate()。

popBackStackImmediate()删除“mBackStack”的顶部,并将其添加到“mTmpRecords”,执行使用的堆栈缓冲区,并标记“mTmpIsPop”,它需要作为弹出操作进行操作。

“流行”是什么意思? 这意味着记录在这一个后栈中的片段操作将被反向执行。

要查看BackStackRecord的executeOps()和executePopOps()以了解更多信息:

void executeOps() {
    final int numOps = mOps.size();
    for (int opNum = 0; opNum < numOps; opNum++) {
        final Op op = mOps.get(opNum);
        final Fragment f = op.fragment;
        if (f != null) {
            f.setNextTransition(mTransition, mTransitionStyle);
        }
        switch (op.cmd) {
            case OP_ADD:
                f.setNextAnim(op.enterAnim);
                mManager.addFragment(f, false);
                break;

void executePopOps(boolean moveToState) {
    for (int opNum = mOps.size() - 1; opNum >= 0; opNum--) {
        final Op op = mOps.get(opNum);
        Fragment f = op.fragment;
        if (f != null) {
            f.setNextTransition(FragmentManagerImpl.reverseTransit(mTransition),
                    mTransitionStyle);
        }
        switch (op.cmd) {
            case OP_ADD:
                f.setNextAnim(op.popExitAnim);
                mManager.removeFragment(f);
                break;

首先在beginTransaction()之后创建一个后台堆栈,然后在add(),remove(),...和commit()之后添加几个片段操作。 FragmentManagerImpl将通过调用其executeOps()来执行您的片段计划 所以也许你可以看到片段A被隐藏,片段B显示为你在屏幕上的计划。

如果您按下后退按钮,活动回调函数调用popBackStackImmediate(),FragmentManagerImpl将通过调用其executePopOps()反向执行您的片段计划。 所以也许你可以看到片段A显示,片段B本能地隐藏为后退按钮动作。