从源码来看Fragment的生命周期(二)

7、moveToState

上一盘说Fragment的生命周期说到了moveToState这个方法,这篇我们继续:

首先看moveToState这个方法的定义:

void moveToState(Fragment f, int newState, int transit, int transitionStyle,boolean keepActive)
static final int INVALID_STATE = -1;   // Invalid state used as a null value.
static final int INITIALIZING = 0;     // Not yet created.
static final int CREATED = 1;          // Created.
static final int ACTIVITY_CREATED = 2; // The activity has finished its creation.
static final int STOPPED = 3;          // Fully created, not started.
static final int STARTED = 4;          // Created and started, not resumed.
static final int RESUMED = 5;          // Created started and resumed.

在moveToState方法一开始,会对传入的newState进行校准,具体方式如下:

//如果传入的newState大于Fragment.CREATED,那么在两种情况下将他强行设置为Fragment.CREATED
//1、这个fragment已经被移除了,即调用removeFragment方法
//2、这个fragment已经没有附着在当前activity上了,即调用了detachFragment方法
if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) {
    newState = Fragment.CREATED;
}
//如果fragment已经被remove掉了,那么如果传入的newState大于原始的mState时,是不能增加mState的值的
if (f.mRemoving && newState > f.mState) {
    // While removing a fragment, we can't change it to a higher state.
    newState = f.mState;
}
//如果fragment要求延时start,并且fragment的原状态小于STARTED,而传入的状态大于STOPPED(最少为STARTED),那么强行将状态置为STOPPED
if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.STOPPED) {
    newState = Fragment.STOPPED;
}

校准完毕之后,就开始同步状态,同步状态有两种情况,一种是传入的newState大于原有的mState,这时状态会上升,另外一种是小于,这时状态会下降。
在状态上升中,是通过switch-case进行不同分支跳转的,但是在这个case的最后并没有使用break语句跳出分支,这时因为在执行完前一个状态的逻辑后,还需要继续往后执行,所有它其中的case分支都是按照INITIALIZING、CREATED、ACTIVITY_CREATED、STOPPED、STARTED、RESUMED顺序排布的,因为代码较长,所以这里都以注释的形式进行说明。

INITIALIZING:

//首先会判断mSavedFragmentState是否为null,这个是用来保存状态恢复而使用的,和Activity非正常销毁时保存状态类似
if (f.mSavedFragmentState != null) {
    ......
}
//配置fragment的参数
......
//验证一些信息
f.mCalled = false;
f.onAttach(mActivity);
if (!f.mCalled) {
    throw new SuperNotCalledException("Fragment " + f
                                      + " did not call through to super.onAttach()");
}
if (f.mParentFragment == null) {
    mActivity.onAttachFragment(f);
}
//执行fragment的生命周期
if (!f.mRetaining) {
    //在这里会调用fragment的performCreate方法,在performCreate方法中会调用生命周期的onCreate方法
    f.performCreate(f.mSavedFragmentState);
}
f.mRetaining = false;
//如果这个fragment是layout中的,那么还执行另外的一些生命周期
if (f.mFromLayout) {
    //performCreateView方法中会调用onCreateView方法
    f.mView = f.performCreateView(f.getLayoutInflater(
                                      f.mSavedFragmentState), null, f.mSavedFragmentState);
    //如果从onCreateView获得的View不为null,那么还会调用onViewCreated方法
    if (f.mView != null) {
        f.mView.setSaveFromParentEnabled(false);
        if (f.mHidden) f.mView.setVisibility(View.GONE);
        f.onViewCreated(f.mView, f.mSavedFragmentState);
    }
}

CREATED:

//因为上面的一个case没有break,所以从第二个case开始,都会先判断newState,才能决定是否继续执行当前state的逻辑
if (newState > Fragment.CREATED) {
    if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
    //如果fragment不是layout中的,那么就会执行fragment的生命周期(和INITIALIZING中类似)
    //不过这里还添加了一个新的逻辑,那就是拿到fragment需要填充的view的id,在fragment的view构建完毕之后,
    //通过container.addView(f.mView),将fragment添加到需要填充的view中,
    if (!f.mFromLayout) {
        ViewGroup container = null;
        if (f.mContainerId != 0) {
            container = (ViewGroup)mContainer.onFindViewById(f.mContainerId);
            if (container == null && !f.mRestored) {
                throwException(new IllegalArgumentException(
                                   "No view found for id 0x"
                                   + Integer.toHexString(f.mContainerId) + " ("
                                   + f.getResources().getResourceName(f.mContainerId)
                                   + ") for fragment " + f));
            }
        }
        f.mContainer = container;
        f.mView = f.performCreateView(f.getLayoutInflater(
                                          f.mSavedFragmentState), container, f.mSavedFragmentState);
        if (f.mView != null) {
            f.mView.setSaveFromParentEnabled(false);
            if (container != null) {
                Animator anim = loadAnimator(f, transit, true,
                                             transitionStyle);
                if (anim != null) {
                    anim.setTarget(f.mView);
                    setHWLayerAnimListenerIfAlpha(f.mView, anim);
                    anim.start();
                }
                container.addView(f.mView);
            }
            if (f.mHidden) f.mView.setVisibility(View.GONE);
            f.onViewCreated(f.mView, f.mSavedFragmentState);
        }
    }
    //执行完生命周期之后,调用ChildFragment中的performActivityCreated方法,这样最终会调用到ChildFragment中的moveToState方法
    f.performActivityCreated(f.mSavedFragmentState);
    if (f.mView != null) {
        f.restoreViewState(f.mSavedFragmentState);
    }
    f.mSavedFragmentState = null;
}

ACTIVITY_CREATED:
STOPPED:

if (newState > Fragment.STOPPED) {
    if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
    //如果newState大于STOPPED(至少是STARTED),那么调用fragment的生命周期onStart方法
    f.performStart();
}

STARTED:

if (newState > Fragment.STARTED) {
    if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
    f.mResumed = true;
    //调用fragment的生命周期onResume
    f.performResume();
    f.mSavedFragmentState = null;
    f.mSavedViewState = null;
}

到这里,提升状态的逻辑基本就说完了,理解完提升状态的逻辑,那么降低状态的逻辑也就大同小异了,这里就放一起说了:

降低状态:

case Fragment.RESUMED:
if (newState < Fragment.RESUMED) {
    if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f);
    //如果小于RESUMED,那么调用生命周期onPause
    f.performPause();
    f.mResumed = false;
}
case Fragment.STARTED:
if (newState < Fragment.STARTED) {
    if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);
    //如果小于STARTED,那么调用生命周期onStop
    f.performStop();
}
case Fragment.STOPPED:
case Fragment.ACTIVITY_CREATED:
if (newState < Fragment.ACTIVITY_CREATED) {
    if (DEBUG) Log.v(TAG, "movefrom ACTIVITY_CREATED: " + f);
    //如果mView不为null,清除之前保存的一些状态
    if (f.mView != null) {
        if (mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) {
            saveFragmentViewState(f);
        }
    }
    //调用onDestroyView生命周期方法
    f.performDestroyView();
    //如果有退出动画,那么播放退出动画
    if (f.mView != null && f.mContainer != null) {
        Animator anim = null;
        if (mCurState > Fragment.INITIALIZING && !mDestroyed) {
            anim = loadAnimator(f, transit, false,
                                transitionStyle);
        }
        if (anim != null) {
            final ViewGroup container = f.mContainer;
            final View view = f.mView;
            final Fragment fragment = f;
            container.startViewTransition(view);
            f.mAnimatingAway = anim;
            f.mStateAfterAnimating = newState;
            anim.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator anim) {
                    container.endViewTransition(view);
                    if (fragment.mAnimatingAway != null) {
                        fragment.mAnimatingAway = null;
                        moveToState(fragment, fragment.mStateAfterAnimating,
                                    0, 0, false);
                    }
                }
            });
            anim.setTarget(f.mView);
            setHWLayerAnimListenerIfAlpha(f.mView, anim);
            anim.start();
        }
        //将fragment的view从界面移除
        f.mContainer.removeView(f.mView);
    }
    f.mContainer = null;
    f.mView = null;
}
case Fragment.CREATED:
if (newState < Fragment.CREATED) {
    if (mDestroyed) {
        //如果fragment的Activity销毁,那么停止fragment的动画,并将mAnimatingAway设置为null
        if (f.mAnimatingAway != null) {
            Animator anim = f.mAnimatingAway;
            f.mAnimatingAway = null;
            anim.cancel();
        }
    }
    if (f.mAnimatingAway != null) {
        //如果mAnimatingAway没有设置为null,那么状态不变
        f.mStateAfterAnimating = newState;
        newState = Fragment.CREATED;
    } else {
        //如果mAnimatingAway状态为null
        if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f);
        if (!f.mRetaining) {
            //调用fragment的生命周期onDestroy
            f.performDestroy();
        }
        f.mCalled = false;
        //调用fragment的生命周期onDetach
        f.onDetach();
        if (!f.mCalled) {
            throw new SuperNotCalledException("Fragment " + f
                                              + " did not call through to super.onDetach()");
        }
        if (!keepActive) {
            if (!f.mRetaining) {
                //回收fragment的index
                makeInactive(f);
            } else {
                f.mHost = null;
                f.mParentFragment = null;
                f.mFragmentManager = null;
                f.mChildFragmentManager = null;
            }
        }
    }
}

总结

①到这里,Fragment的源码也算是基本完结了,相比于Activity,Fragment更像一个java类,它没有Activity那样实现很多的视图接口,也没有实现任何的键盘监听,从这里我们就可以确定fragment里的键盘事件应该是通过Activity传入的。
②在我们使用Fragment的时候,通过getFragmentManager方法拿到的其实是FragmentManagerImpl,他是FragmentManagerI的子类。而Fragment的生命周期,也是通过它进行控制的。
③在我们通过beginTransaction,add方法添加Fragment的时候,只是把Fragment和操作类型保存到一个BackStackRecord的Op对象中去了,虽然Fragment对象是通过我们new Fragment创建出来的,但是此时的Fragment并没有执行它生命周期的onCreate方法,这点和Activity是不同的,Activity是会在系统创建它之后,立刻执行它出onCreate方法。
④对Fragment状态的的变更,是在我们调用完commit方法后才开始的,他会通过mHandler.post(mExecCommit),最后调用到execPendingActions方法中。
⑤在execPendingActions方法中,会拿到之前在BackStackRecord对象,而BackStackRecord是实现了Runnable接口是,所以会执行BackStackRecord中的run方法。
⑥在BackStackRecord 的run中,会针对不同的操作类型,比如add,remove调用FragmentManagerImpl中不同的方法,例如addFragment,removeFragment,在这些方法中,首先会更改fragment对象中对应的配置参数,然后会将fragment传入调用moveToState方法。
⑦在FragmentManagerImpl的moveToState方法中,会调用Fragment的生命周期方法。

上述,就是Fragment源码中,对于Fragment生命周期的调用了,当然还是那句话,Android的源码远比我看的复杂,而我当前也只是通过一个简单的例子来看Fragment的生命周期,自然不可能面面俱到,至于其中的细节部分,还是需要以后慢慢研究咯。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Android开发中,Fragment是一个可重用的UI部分,它可以独立于Activity存在,并且可以根据需要添加到不同的Activity中。Fragment有自己的生命周期管理,这包括一系列的方法,用于描述Fragment从创建、显示、活跃到销毁的整个过程。 1. **onCreate()**: 当Fragment实例被创建时调用,这是初始化阶段,可以在此设置基本属性和数据。 2. **onCreateView()**: 如果Fragment没有预先创建视图,这个方法会被调用来生成视图。返回null则会使用默认布局。 3. **onStart()**: 当Fragment成为活动焦点或可见时调用,可以在这里开始执行耗时操作。 4. **onResume()**: 当Fragment变为活动的前景或者用户正在交互时,这个方法会被调用,意味着它是完全活跃的。 5. **onPause()**: 当Fragment不再接收用户交互或成为活动焦点时,但依然可见时,这个方法会被调用。 6. **onStop()**: 当Fragment失去焦点并且不处于可见状态时,例如切换到其他Activity,这个方法会被调用。 7. **onDestroyView()**: 当Fragment的视图不再需要时,这个方法会被调用,通常在onPause之后。 8. **onSaveInstanceState()**: 在onPause或onStop之前调用,用于保存Fragment的状态,以便在恢复时使用。 9. **onDestroy()**: 当Fragment被系统卸载,不再需要内存时,这个方法会被调用。 10. **onActivityCreated()**: 当Fragment的视图已经创建完毕,并且所有的依赖项都可用时,这个方法会被调用。 11. **onDestroyView()**: 视图销毁后调用,释放资。 12. **onDetach()**: 当Fragment从其宿主Activity中分离出来时,这个方法会被调用,通常发生在用户切换回其他Activity时。 理解Fragment生命周期对于管理其行为、数据和资至关重要。开发者可以根据这些阶段进行必要的资管理、数据保存和状态更新。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值