博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Fragment之设计思路
阅读量:4179 次
发布时间:2019-05-26

本文共 5699 字,大约阅读时间需要 18 分钟。

对于Fragment,相信做过android的肯定或多或少的都用过,但是你对它的实现原理是否知道,这里我们就从一个大的方向来看看它是如何设计的。

Fragment是有生命周期的,和Activity类似,我们可以把fragment看成是activity的一部分,fragment的生命周期其实就是由activity来控制的,只不过fragment内部又做了一些细致的划分,这也就是为什么我们会在fragment中多出一些方法的回调,这里有一个点需要注意,activity并不是直接控制fragment的,他们中间隔着一个FragmentManager,那这个FragmentManager又是什么呢?我们可以理解为是一个可以感知activity生命周期的,负责管理fragment的类,它里面有一个集合就是负责收集添加进activity的fragment,也就是ArrayList,我们知道,在fragment中能做一些只能在activity中做的事情,这个又是怎么实现的呢?这个用到的就是回调了,涉及到的一个抽象类是FragmentHostCallback,这个类在FragmentActivity中有实现,当在fragment中使用调用startActivity()时,其实最终调用到的还是Activity中startActivity(),下面就从源码中来看看,主要是看流程,不会涉及到细节。
先来看下FragmentActivity中定义的一个成员变量:

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

这里涉及到两个类:

1、FragmentController :主要作用是Activity到Fragment通信;
2、HostCallbacks:主要作用是Fragment到Activity通信,它继承自FragmentHostCallback;
这里先来看下HostCallbacks的构造方法:

class HostCallbacks extends FragmentHostCallback
{
public HostCallbacks() {
super(FragmentActivity.this /*fragmentActivity*/); } ... }

又调用了父类的构造方法,并将FragmentActivity传进去,跟着往下走:

public abstract class FragmentHostCallback
extends FragmentContainer {
private final Activity mActivity; final Context mContext; private final Handler mHandler; final int mWindowAnimations; final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl(); private SimpleArrayMap
mAllLoaderManagers; private LoaderManagerImpl mLoaderManager; private boolean mCheckedForLoaderManager; private boolean mLoadersStarted; public FragmentHostCallback(Context context, Handler handler, int windowAnimations) {
this(null /*activity*/, context, handler, windowAnimations); } FragmentHostCallback(FragmentActivity 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; } public void onStartActivityFromFragment(Fragment fragment, Intent intent, int requestCode) {
if (requestCode != -1) {
throw new IllegalStateException( "Starting activity with a requestCode requires a FragmentActivity host"); } mContext.startActivity(intent); } ... }

可以看到这里将activity和handler保存了起来,这样当Fragment中有需要执行Fctivity的方法时,就可以通过这个保存的变量来实现了,比如,当在fragment中调用startActivity()时,最后调用到的就是这里的onStartActivityFromFragment(),还有其他一些Fragment回调到Activity的方法都是定义在这里。这里有一个需要特别注意的属性mFragmentManager ,它就是管理Fragment的,activity涉及到对fragment的操作都是通过他来实现的,比如activity对fragment生命周期分发。

在来FragmentActivity的各个生命周期方法中可以发现,都会使用到mFragments,这里以FragmentActivity的onCreate()方法为例,来看下他对mFragments的使用:

@Override    protected void onCreate(@Nullable Bundle savedInstanceState) {
mFragments.attachHost(null /*parent*/); super.onCreate(savedInstanceState); //以下部分是对Fragment状态的恢复,想进一步了解的可以看下上一篇: Fragment之setRetainInstance详解 NonConfigurationInstances nc = (NonConfigurationInstances) getLastNonConfigurationInstance(); if (nc != null) {
mFragments.restoreLoaderNonConfig(nc.loaders); } if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG); mFragments.restoreAllState(p, nc != null ? nc.fragments : null); } //Fragment将会执行对应的生命周期方法,其他的生命周期类似,这里就不一一去看了 mFragments.dispatchCreate(); }

可以看到这里全是对Fragment的处理,其中mFragments.dispatchCreate()是分发对应的生命周期,fragment中的生命周期都是以这种方式分发下去的,这也就是fragment和activity的生命周期是对应的,这里在主要来看下mFragments.attachHost(null /parent/),看下它里面做了些什么:

public class FragmentController {
private final FragmentHostCallback
mHost; public static final FragmentController createController(FragmentHostCallback
callbacks) {
return new FragmentController(callbacks); } private FragmentController(FragmentHostCallback
callbacks) {
mHost = callbacks; } public FragmentManager getSupportFragmentManager() {
return mHost.getFragmentManagerImpl(); } public LoaderManager getSupportLoaderManager() {
return mHost.getLoaderManagerImpl(); } public void attachHost(Fragment parent) {
mHost.mFragmentManager.attachController( mHost, mHost /*container*/, parent); } ...}

先看下它的构造方法,将HostCallbacks 对象保存到了mHost中,再来看下它的attacHost()方法,使用到了mFragmentManager,它是在FragmentHostCallback中实例化的,上面也有提到,它是一个FragmentManagerImpl对象,跟着attachController()这个方法进去看看:

final class FragmentManagerImpl extends FragmentManager implements LayoutInflaterFactory {
... FragmentHostCallback mHost; FragmentContainer mContainer; Fragment mParent; public void attachController(FragmentHostCallback host, FragmentContainer container, Fragment parent) {
if (mHost != null) throw new IllegalStateException("Already attached"); mHost = host; mContainer = container; mParent = parent; } ....}

也没什么,就是初始化一些变量,这里注意这个mHost,当在fragment需要调回到activity时,用到的就是mHost(也就是FragmentHostCallback),到这里,对于FragmentManager的准备工作就算是完成了,接下开就是使用了,下一篇再来介绍fragment的工作流程。

#总结
1、链接Activity和Fragment的点是FragmentHostCallback;
2、Fragment向Activity通信通过FragmentHostCallback定义的方法进行回调;
3、FragmentHostCallback中实例化了FragmentManagerImpl ,管理着所有添加的Fragment的,Activity向Fragment通信就是通过他来实现的;
4、为了剥离Activity向Fragment的通信,使用FragmentController 对FragmentManagerImpl 进行代理,这样就可以使用FragmentController 对Fragment进行通信了。

转载地址:http://xkhai.baihongyu.com/

你可能感兴趣的文章
Apache Maven项目提供的AntRun插件详解
查看>>
Apache Maven项目提供的EJB插件详解
查看>>
Hibernate中持久化上下文的flush操作之一COMMIT
查看>>
Hibernate的乐观锁并发控制机制
查看>>
Hibernate的悲观锁并发控制机制及LockMode
查看>>
Hibernate中的数据的获取策略(fetching)
查看>>
Hibernate中通过HQL/JPQL查询的方式实现动态数据获取
查看>>
Hibernate中通过FetchProfile的方式实现动态数据获取
查看>>
Hibernate应用中通过JPA配置Entity缓存
查看>>
Hibernate中配置二级缓存的并发策略
查看>>
Hibernate中的Query cache(查询缓存)
查看>>
Hibernate的interceptors与events
查看>>
Android常用代码
查看>>
Cardboard虚拟现实开发初步(二)
查看>>
60个优秀的免费3D模型下载网站
查看>>
Cardboard虚拟现实开发初步(三)
查看>>
Android native和h5混合开发几种常见的hybrid通信方式
查看>>
Vista/Win7 UAC兼容程序开发指南
查看>>
IOS程序开发框架
查看>>
安装jdk的步骤
查看>>