1、概述Fragment机制

1、Android3.0引入,可以给大屏幕动态界面设计提供支持。

2、现在主要用在一个页面内嵌多个Tab时使用。

2、Fragment机制原理总结

当前Android最新版本已经是R,Fragment机制也增加了不少改动,复杂了很多,为了单纯了解核心机制,最快的方法可以直接从最初的代码入手。

初版Fragment机制,三个核心类:

1)FragmentManager:

控制Fragment的生命周期,核心是控制Fragment的view状态,比如将fragment中的view添加到Activity中或者将view从Activity中移除,第一版时FragmentManager是放在Activity里的。

2)Fragment:

应用的一个UI片段或行为,可以在Activity中被替换,持有自己的View,定义了自己的生命周期,但是生命周期依赖于依附的Activity的生命周期,当Activity销毁时,Fragment同时也会被销毁。

3)FragmentTransactionImpl(FragmentTransaction的实现类):

对外提供控制Fragment操作的接口,初版只有添加、移除和comit操作,添加和移除只是对添加队列和移除队列操作,commit时委托FragmentManager真正执行操作,设置Fragment的生命周期状态。

初版类图

初版时序图

当前最新的Fragment机制:

为了将Activity和FragmentManager解耦,方便其他地方也可以使用Fragment,比如我们其实可以在service中使用Fragment,虽然场景不是很多。

比如如下博客:

https://blog.csdn.net/mjlong123123/article/details/104156953

4)FragmentController:

FragmentController中的“所有”动作真正执行者都是FragmentHostCallback,绝大部分大部分的动作真正执行者是FragmentHostCallback中的FragmentManager。

5)HostCallbacks(FragmentHostCallback):

为了将FragmentManager于FragmentManager解耦,必须有一个中间类来真正持有FragmentManager对象,这个类就是FragmentHostCallback,Activity中的实现是HostCallbacks,当然,如果我们想要在service中使用Fragment,可以自定义类来继承FragmentHostCallback类来实现。

实际调用链

Activity->FragmentController->FragmentHostCallback->FragmentManager,

BackStackRecord(FragmentTransaction的实现类):第一版时叫FragmentTransactionImpl,对外提供控制Fragment操作的接口,比如添加或移除。

3、细节

P版本Fragment机制

类图

时序图,以下面的代码为例

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    LearnFragment fragment = new LearnFragment();
    fragmentTransaction.add(R.id.fragment_contain, fragment);
    fragmentTransaction.commit();
}

    void moveToState(Fragment f, int newState, int transit, int transitionStyle,
            boolean keepActive) {
        ...
        if (f.mState <= newState) {
            ...
            switch (f.mState) {
                case Fragment.INITIALIZING:
                    if (newState > Fragment.INITIALIZING) {
                        ...
                        f.onAttach(mHost.getContext());
                        ...
                        if (f.mParentFragment == null) {
                            mHost.onAttachFragment(f);
                        } 
                      ...
                        if (!f.mIsCreated) {
...
                            f.performCreate(f.mSavedFragmentState);
                            dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
                        } ...
                    }
                    // fall through
                case Fragment.CREATED:
                    ...
                    if (newState > Fragment.CREATED) {
                        if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
                        if (!f.mFromLayout) {
                            ViewGroup container = null;
                            ...
                            f.mView = f.performCreateView(f.performGetLayoutInflater(
                                    f.mSavedFragmentState), container, f.mSavedFragmentState);
                            if (f.mView != null) {
                                ...
                                    container.addView(f.mView);
                                ...
                                f.onViewCreated(f.mView, f.mSavedFragmentState);
                                ....
                            }
                        }

                        f.performActivityCreated(f.mSavedFragmentState);
                        ...
                    }
                    // fall through
                case Fragment.ACTIVITY_CREATED:
                    ...
                    // fall through
                case Fragment.STOPPED:
...
                        f.performStart();
...
                    // fall through
                case Fragment.STARTED:
...
                        f.performResume();
...
            }
        } else if (f.mState > newState) {
            switch (f.mState) {
                case Fragment.RESUMED:
...
                        f.performPause();
...
                    // fall through
                case Fragment.STARTED:
...
                        f.performStop();
...
                    // fall through
                case Fragment.STOPPED:
                case Fragment.ACTIVITY_CREATED:
...
                        f.performDestroyView();
...
                            f.mContainer.removeView(f.mView);
...
                    // fall through
                case Fragment.CREATED:
...
                                f.performDestroy();
...
                            f.performDetach();
                            ...
            }
        }
...
            f.mState = newState;
...
    }

FragmentTransaction:是接口类型,实现类在Activity中,为FragmentTransactionImpl

private final class FragmentTransactionImpl implements FragmentTransaction {
    ArrayList<Fragment> mAdded;
    ArrayList<Fragment> mRemoved;
    
    public FragmentTransaction add(Fragment fragment, int containerViewId) {
        return add(fragment, null, containerViewId);
    }

    public FragmentTransaction add(Fragment fragment, String name, int containerViewId) {
        if (fragment.mActivity != null) {
            throw new IllegalStateException("Fragment already added: " + fragment);
        }
        if (name != null) {
            fragment.mName = name;
        }
        if (mRemoved != null) {
            mRemoved.remove(fragment);
        }
        if (mAdded == null) {
            mAdded = new ArrayList<Fragment>();
        }
        fragment.mContainerId = containerViewId;
        mAdded.add(fragment);
        return this;
    }

    public FragmentTransaction remove(Fragment fragment) {
        if (fragment.mActivity == null) {
            throw new IllegalStateException("Fragment not added: " + fragment);
        }
        if (mAdded != null) {
            mAdded.remove(fragment);
        }
        if (mRemoved == null) {
            mRemoved = new ArrayList<Fragment>();
        }
        mRemoved.add(fragment);
        return this;
    }

    public void commit() {
        if (mRemoved != null) {
            for (int i=mRemoved.size()-1; i>=0; i--) {
                mFragments.removeFragment(mRemoved.get(i));
            }
        }
        if (mAdded != null) {
            for (int i=mAdded.size()-1; i>=0; i--) {
                mFragments.addFragment(mAdded.get(i));
            }
        }
        if (mFragments != null) {
            mFragments.moveToState(mFragments.mCurState);
        }
    }
}

Activity:

final void performCreate(Bundle icicle) {
    onCreate(icicle);
    mFragments.dispatchCreate(icicle);
}
    
final void performStart() {
    mCalled = false;
    mInstrumentation.callActivityOnStart(this);
。。。
    mFragments.dispatchStart();
}
    
final void performResume() {
    performRestart();
。。。
    mInstrumentation.callActivityOnResume(this);
。。。
        
    mFragments.dispatchResume();
        
    onPostResume();
。。。
}

final void performPause() {
    mFragments.dispatchPause();
    onPause();
}
    
final void performStop() {
。。。
     mFragments.dispatchStop();
。。。
     mInstrumentation.callActivityOnStop(this);
。。。
}
    
final void performDestroy() {
    mFragments.dispatchDestroy();
    onDestroy();
}