Fragment生命周期情景分析和源码分析

  • onAttach():Fragment和Activity相关联时调用。可以通过该方法获取Activity引用,还可以通过getArguments()获取参数。
  • onCreate():Fragment被创建时调用。
  • onCreateView():创建Fragment的布局。
  • onActivityCreated():当Activity完成onCreate()时调用。
  • onStart():当Fragment可见时调用。
  • onResume():当Fragment可见且可交互时调用。
  • onPause():当Fragment不可交互但可见时调用。
  • onStop():当Fragment不可见时调用。
  • onDestroyView():当Fragment的UI从视图结构中移除时调用。
  • onDestroy():销毁Fragment时调用。
  • onDetach():当Fragment和Activity解除关联时调用。


因为Fragment分为静态和动态两种,所以我们先将简单的,说说静态的Fragment生命周期。然后又因为Fragment是依附Activity的,所以两者的生命周期是同步的。最后就是注意我说的Fragment的包是android.app。


1.静态Fragment


启动Activity,Fragment的onAttach、onCreate、onCreateView、onActivityCreated对应Activity的onCreate,Fragment的onStart对应Activity的onStart,Fragment的onResume对于Activity的onResume


Fragment onAttach
Fragment onCreate
Fragment onCreateView
Activity onCreate
Fragment onActivityCreated
Activity onStart
Fragment onStart
Activity onResume
Fragment onResume

当前Activity跳转到其他Activity,Fragment的onPause对应Activity的onPause,Fragment的onSavaInstanceState、onStop对于Activity的onStop

Fragment onPause
Activity onPause
Fragment onSaveInstanceState
Fragment onStop
Activity onStop

然后返回原来的Activity,

Activity onRestart
Activity onStart
Fragment onStart
Activity onResume
Fragment onResume

退出应用,Fragment的onDestroyView、onDestroy、onDetach对应Activity的onDestroy

Fragment onPause
Activity onPause
Fragment onStop
Activity onStop
Fragment onDestroyView
Fragment onDestroy
Fragment onDetach
Activity onDestroy


2.动态Fragment

添加一个Fragment到FrameLayout

        FragmentManager fm = getFragmentManager();
        FragmentTransaction transaction = fm.beginTransaction();
        transaction.add(R.id.mycontent, fmList[1], fmTag[1]);
        transaction.commit();

生命周期变化倒是只有Fragment创建和显示

Fragment onAttach
Fragment onCreate
Fragment onCreateView
Fragment onActivityCreated
Fragment onStart
Fragment onResume

切换Fragment,原来的Fragment隐藏,新的Fragment的添加

            transaction.hide(fm_one);
            transaction.add(R.id.mycontent, fmList[two], fmTag[two]);

原来的Fragment没有生命周期的变化

如果Fragment被移除

transaction.remove()

生命周期变化就是Fragment变成不可见,然后被销毁

Fragment onPause
Fragment onStop
Fragment onDestroyView
Fragment onDestroy
Fragment onDetach

3.源码分析

onAttach

onAttach这个函数,就是为了判断是否有依附的Activity,如果有就给mCalled赋值true,否则赋值false

    @CallSuper
    public void onAttach(Context context) {
        mCalled = true;
        final Activity hostActivity = mHost == null ? null : mHost.getActivity();
        if (hostActivity != null) {
            mCalled = false;
            onAttach(hostActivity);
        }
    }

    /**
     * @deprecated Use {@link #onAttach(Context)} instead.
     */
    @Deprecated
    @CallSuper
    public void onAttach(Activity activity) {
        mCalled = true;
    }

这个mHost是在哪里获取的Activity,我们找找看

  FragmentHostCallback mHost;

额,在Fragment的源码里没找到,哎看看这个类的源码再说,虽然知道Activity是在初始化时获得的

    public FragmentHostCallback(Context context, Handler handler, int windowAnimations) {
        this((context instanceof Activity) ? (Activity)context : null, context,
                chooseHandler(context, handler), windowAnimations);
    }

    FragmentHostCallback(Activity activity) {
        this(activity, activity /*context*/, activity.mHandler, 0 /*windowAnimations*/);
    }

    FragmentHostCallback(Activity activity, Context context, Handler handler,
            int windowAnimations) {
        mActivity = activity;
        mContext = context;
        mHandler = handler;
        mWindowAnimations = windowAnimations;
    }



Activity getActivity() {
        return mActivity;
    }

这个类的初始化在哪里弄得呢

FragmentManager fm = getFragmentManager();

继续追

    public FragmentManager getFragmentManager() {
        return mFragments.getFragmentManager();
    }

这个mFragments不是Fragment类对象

    final FragmentController mFragments = FragmentController.createController(new HostCallbacks());

看createController函数源码是如何创建FragmentController对象

    public static final FragmentController createController(FragmentHostCallback<?> callbacks) {
        return new FragmentController(callbacks);
    }

然后这个new的时候还把涉及了mHost这个熟悉的变量,果然是FragmentHostCallback这个类

    private FragmentController(FragmentHostCallback<?> callbacks) {
        mHost = callbacks;
    }


private final FragmentHostCallback<?> mHost;

最后可以得出Fragment获取依附的Activity不是在onAttach里完成的,而是在Activity里执行getFragmentManager完成的

onCreate

再来看看onCreate的源码,感觉他是在判断自己是否嵌套了Fragment,如果有就初始化子Fragment,并判断是否有子View

    @CallSuper
    public void onCreate(@Nullable Bundle savedInstanceState) {
        mCalled = true;
        final Context context = getContext();
        final int version = context != null ? context.getApplicationInfo().targetSdkVersion : 0;
        if (version >= Build.VERSION_CODES.N) {
            restoreChildFragmentState(savedInstanceState, true);
            if (mChildFragmentManager != null
                    && !mChildFragmentManager.isStateAtLeast(Fragment.CREATED)) {
                mChildFragmentManager.dispatchCreate();
            }
        }
    }

    void restoreChildFragmentState(@Nullable Bundle savedInstanceState, boolean provideNonConfig) {
        if (savedInstanceState != null) {
            Parcelable p = savedInstanceState.getParcelable(Activity.FRAGMENTS_TAG);
            if (p != null) {
                if (mChildFragmentManager == null) {
                    instantiateChildFragmentManager();
                }
                mChildFragmentManager.restoreAllState(p, provideNonConfig ? mChildNonConfig : null);
                mChildNonConfig = null;
                mChildFragmentManager.dispatchCreate();
            }
        }
    }



    void instantiateChildFragmentManager() {
        mChildFragmentManager = new FragmentManagerImpl();
        mChildFragmentManager.attachController(mHost, new FragmentContainer() {
            @Override
            @Nullable
            public <T extends View> T onFindViewById(int id) {
                if (mView == null) {
                    throw new IllegalStateException("Fragment does not have a view");
                }
                return mView.findViewById(id);
            }

            @Override
            public boolean onHasView() {
                return (mView != null);
            }
        }, this);
    }

onCreateView

这个函数是空的,没有去实现任何东西,所以我们在实现这个函数的时候不需要调用父类的函数

    @Nullable
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
            Bundle savedInstanceState) {
        return null;
    }

onActivityCreated

就是给mCalled赋值true

    @CallSuper
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        mCalled = true;
    }

onStart


这个mLoaderManager是用来管理这个Fragment的生命周期

    @CallSuper
    public void onStart() {
        mCalled = true;

        if (!mLoadersStarted) {
            mLoadersStarted = true;
            if (!mCheckedForLoaderManager) {
                mCheckedForLoaderManager = true;
                mLoaderManager = mHost.getLoaderManager(mWho, mLoadersStarted, false);
            } else if (mLoaderManager != null) {
                mLoaderManager.doStart();
            }
        }
    }


    void doStart() {
        if (DEBUG) Log.v(TAG, "Starting in " + this);
        if (mStarted) {
            RuntimeException e = new RuntimeException("here");
            e.fillInStackTrace();
            Log.w(TAG, "Called doStart when already started: " + this, e);
            return;
        }
        
        mStarted = true;

        // Call out to sub classes so they can start their loaders
        // Let the existing loaders know that we want to be notified when a load is complete
        for (int i = mLoaders.size()-1; i >= 0; i--) {
            mLoaders.valueAt(i).start();
        }
    }

接下来几个函数都是只给mCalled赋值为true

    @CallSuper
    public void onResume() {
        mCalled = true;
    }



    @CallSuper
    public void onPause() {
        mCalled = true;
    }


    @CallSuper
    public void onStop() {
        mCalled = true;
    }

    @CallSuper
    public void onDestroyView() {
        mCalled = true;
    }

onDestroy

通过mLoaderManager来销毁Fragment

    @CallSuper
    public void onDestroy() {
        mCalled = true;
        //Log.v("foo", "onDestroy: mCheckedForLoaderManager=" + mCheckedForLoaderManager
        //        + " mLoaderManager=" + mLoaderManager);
        if (!mCheckedForLoaderManager) {
            mCheckedForLoaderManager = true;
            mLoaderManager = mHost.getLoaderManager(mWho, mLoadersStarted, false);
        }
        if (mLoaderManager != null) {
            mLoaderManager.doDestroy();
        }
    }


这个mLoaderManager.doDestroy把mHost给赋值为空

    void doDestroy() {
        if (!mRetaining) {
            if (DEBUG) Log.v(TAG, "Destroying Active in " + this);
            for (int i = mLoaders.size()-1; i >= 0; i--) {
                mLoaders.valueAt(i).destroy();
            }
            mLoaders.clear();
        }
        
        if (DEBUG) Log.v(TAG, "Destroying Inactive in " + this);
        for (int i = mInactiveLoaders.size()-1; i >= 0; i--) {
            mInactiveLoaders.valueAt(i).destroy();
        }
        mInactiveLoaders.clear();
        mHost = null;
    }


onDetach

    @CallSuper
    public void onDetach() {
        mCalled = true;
    }

总结:Fragment是通过mHost与Activity联系的,通过mLoaderManager来控制Fragment的初始化和运行、销毁,还有保存相关数据

参考文章:

https://cloud.tencent.com/developer/article/1035535

这里还有一篇Activity生命周期的博客

https://blog.csdn.net/z979451341/article/details/64440408


猜你喜欢

转载自blog.csdn.net/z979451341/article/details/79878458