以前也用过Fragment,大多数是结合ViewPager,使用support-v4里的类,但是对Fragment的只是停留在简单的使用,对具体的生命周期调用和Fragment的实现原理都不太清楚,最近看了一下Fragment相关的源码,在这里整理一下,加深理解,也防着以后又给忘了
总结:Fragment实现了对View进行异步动态添加移除管理,在这一点上相当于我们自己封装View进行相关业务处理;同时Fragment与Activity之间有生命周期的关联,实现了自动的生命周期管理(比自定义View要方便多了);FragmentManager实现了Fragment操作的事务管理
Fragment与Activity的关联
FragmentManager mFragmentMgr= getFragmentManager();
FragmentTransaction trans=mFragmentManager.beginTransact();
在Activity里直接使用Fragment一般都会用到这两句,v4里的Fragment Activity的getSupportFragmentManager类似,使用ViewPager会用到这个
1.FragmentHostCallback
Integration points with the Fragment host.
Fragments may be hosted by any object; such as an {@link Activity}. In order to
host fragments, implement {@link FragmentHostCallback}, overriding the methods
applicable to the host.
FragmentHostCallBack是Fragment与宿主,确切的说是FragmentManager与宿主相关联的连接点,这里说为了能够承载Fragment(做Fragment 的宿主)需要实现FragmentHostCallBack,但这是一个抽象类,实际上Activity也没法继承该类;具体实现是Activity的内部类HostCallBack继承了该类,
内部类可以拿到Activity的信息。
public abstract class FragmentHostCallback<E> extends FragmentContainer {
private final Activity mActivity;
final Context mContext;
private final Handler mHandler;
final int mWindowAnimations;
final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();
private ArrayMap<String, LoaderManager> mAllLoaderManagers;
private LoaderManagerImpl mLoaderManager;
private boolean mCheckedForLoaderManager;
private boolean mLoadersStarted;
该类既持有了Activity 相关引用,有持有了FragmentManagerImpl引用,在Activity与Fragment之间扮演中介者角色(中介者模式),对Fragment系统来说是对外衔接的接口。在Activity内部类HostCallBack中
class HostCallbacks extends FragmentHostCallback<Activity> { public HostCallbacks() { super(Activity.this /*activity*/); }
创建HostCallbacks对象的时候对mActivity,mContext,mHandler进行了赋值,Activity通过FragmentController拿到HostCallbacks引用
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
..................
public FragmentManager getFragmentManager() { return mFragments.getFragmentManager(); }
但是FragmentManagerImpl构造并没有拿到HostCallbacks引用,在Activity的attach放法中调用了FragmentController的attachHost
mFragments.attachHost(null /*parent*/);/** * Attaches the host to the FragmentManager for this controller. The host must be * attached before the FragmentManager can be used to manage Fragments. * */ public void attachHost(Fragment parent) { mHost.mFragmentManager.attachController( mHost, mHost /*container*/, parent); }在Fragmentmanagerimpl中,Fragmentmanagerimpl也拿到了HostCallBack的引用,完成关联public void attachController(FragmentHostCallback<?> host, FragmentContainer container, Fragment parent) { if (mHost != null) throw new IllegalStateException("Already attached"); mHost = host; mContainer = container; mParent = parent; }Activity的attach方法是在系统创建Activity对象后就会调用的,也就是在 Activity 常见后就完成了与FragmentManager的关联,当通过
fragmentManager添加Fragment之后,会把HostCallBack引用赋给Fragment对应的成员变量
相互持有引用之后Activity可以在生命周期回调中通过FragmentController的一系列dispatchXXXX方法完成对Fragment生命周期的关联