Fragment运行机制源码分析(一)

尊重原创:http://blog.csdn.net/yuanzeyao/article/details/52822315


Fragment是Android3.0中推出的,目的是方便屏幕适配,虽然推出时间比较早,但是由于Fragment本身存在着各种Bug,并且使用起来比Activity复杂得多,所以真正掌握Fragment运行机制的同学并不多。在网上经常可以看到开发者对Fragment各种吐槽,认为在App中根本没有必要使用Fragment,因为使用View也可以完成Fragment的一样的功能,对于这种说法也不完全错,我们公司也是因为Fragment存在各种bug,从而自己写了一套类似Fragment机制的框架,并且使用起来非常简单,有bug自己也非常容易修复。但是我个人认为毕竟Fragment是google提供的,并会长期维护,所以相信以后Fragment会越来越稳定,所以我们还是有必要理解Fragment的运行机制,从而当我们使用过程中出现Bug时,我们有办法进行处理。由于Fragment是在3.0系统引入,所以对于2.x系统,如果想使用Fragment,那么需要依赖support_v4包,对于不同版本的support_v4包源码并不一样(support_v4包的源码和系统中Fragment的源码也不一定一样),本系列文章使用的support_v4版本是23.2.1.

简单介绍本系列文章目录:

  1. Fragmeng生命周期
  2. Fragment和Activity生命周期如何联动
  3. FragmentTransaction的add,replace,remove,show,hide等操作都做了什么
  4. Fragment的销毁和重建机制
  5. addToBackStack系列方法和popBackStack系列方法源码解析
  6. 无UI Fragment的使用
  7. Fragment动画机制分析

Fragment生命周期

以上内容就是本系列文章会详细介绍的,那么我们先来看看Fragment的生命周期,在具体介绍生命周期之前,我们看看官方给出的生命周期图:
这里写图片描述

从上图可以看出Fragment的生命周期和Activity的生命周期极其类似,只不过生命周期分得更加细致,例如当Activity的生命周期进入onCreate阶段时,那么该Activty中的Fragment中的onAttach,onCreate,onCreateView,onActivityCreated等方法均会被调用。不同的是,Activity的生命周期是被Android系统(严格说是AMS)管理,Fragment的生命周期是被所属Activity管理。那么Activity是如何管理Fragment的生命周期呢?他们的生命周期是如何联动起来的呢?下面我就来为您解答这两个问题。

Fragment和Activity生命周期联动机制

同样在介绍Activity如何管理Fragment生命周期之前,我们先来看一个类图。
这里写图片描述

从这种图里面我们可以获取一下信息:

  • 如果要使用Fragment,那么你的Activity需要继承FragmentActivity(本系列文章讨论的都是support库的Fragment).
  • FragmentActivity中有一个属性:mFragments,该属性类型是FragmentController.
  • FragmentController类中有一个属性mHost,类型是FragmentHostCallback,它是一个抽象类,实现者是HostCallback.
  • FragmentHostCall有两个重要的属性:mActivity和,mFragmentManager. mActivity就是前面说的FragmentActivity,而mFragmentManager是FragmentManagerImpl类型.
  • FragmentManagerImpl从名字看来就是用来管理Fragment的,它实现了FragmentManager接口,并且它有一个mHost属性,类型为FragmentHostBack.
  • FragmentActivity可以通过mFragment调用到FragmentManager里面的逻辑.
  • FragmentManager可以通过mHost调用到FragmentActivity中的逻辑.

分析完类图之后,我们知道FragmentActivity和FragmentManager之间可以通过FragmentHostCallback进行互相调用,那么接下来我们就从代码的角度看看我们是如何交互的。

代码 1:FragmentActivity的onCreate方法


    /**
     * Perform initialization of all fragments and loaders.
     */
    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        mFragments.attachHost(null /*parent*/);

        super.onCreate(savedInstanceState);
        //....忽略部分代码
        mFragments.dispatchCreate();
    }

为了便于大家分析,我删除了onCreate中一些不相干的逻辑。可以看到在onCreate方法的第一句就调用了mFragment的attachHost方法,经过前面的分析,mFragments就是FragmentController对象,我们先来看看mFragment是如何赋值的。

代码2:FragmentActivity的mFragments属性初始化

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

从这里可以知道使用HostCallBacks对FragmentController中的mHost属性进行初始化。
接下来我们进入到FragmentController的attachHost方法看看。

代码3:FragmentController的attachHost方法

/**
     * 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);
    }

attachHost方法远比我们想象的简单,里面就是调用了mHost.mFragmentManager的attachController方法。通过前面的分析,其实就是调用了FragmentManagerImpl的attachController方法,所以我们顺藤摸瓜,进入FragmentManagerImpl看看。

代码 4:FragmentManagerImpl 的attachController

 public void attachController(FragmentHostCallback host,
            FragmentContainer container, Fragment parent) {
        if (mHost != null) throw new IllegalStateException("Already attached");
        mHost = host;
        mContainer = container;
        mParent = parent;
    }

attachController方法也是相当的简单,就是对FragmentManager中的mHost,mContainer,mParent三个属性进行赋值。

到这里我们就知道FragmentActivity和FragmentManager是如何关联起来的,接下来我们看看Activity是如何管理Fragment的生命周期的。

在FragmentActivity的onCreate方法中还调用了一个方法

mFragments.dispatchCreate();

同样,我们进入到FragmentController的dispatchCreate方法
代码5 :FragmentController的dispatchCreate方法

/**
     * Moves all Fragments managed by the controller's FragmentManager
     * into the create state.
     * <p>Call when Fragments should be created.
     *
     * @see Fragment#onCreate(Bundle)
     */
    public void dispatchCreate() {
        mHost.mFragmentManager.dispatchCreate();
    }

可以看到FragmentController并没有任何逻辑,仅仅是调用了FragmentManagerImpl的同名方法

代码6 :FragmentManagerImpl的dispatchCreate方法

public void dispatchCreate() {
        mStateSaved = false;
        moveToState(Fragment.CREATED, false);
    }

dispatchCreate方法里面调用了一个叫moveToState的方法,同样,细心的同学会发现Activity的其他生命周期方法(onStart,onResume..)都会调用到FragmentManagerImpl的dispatchXXX的方法中,最终都调用到了moveToState这个方法,moveToState这个方法有多个同名的方法,最终调用的代码如下:
代码 7:FragmentManagerImpl的movetoState方法

void moveToState(int newState, int transit, int transitStyle, boolean always) {
        if (mHost == null && newState != Fragment.INITIALIZING) {
            throw new IllegalStateException("No host");
        }

        if (!always && mCurState == newState) {
            return;
        }

        mCurState = newState;
        if (mActive != null) {
            boolean loadersRunning = false;
            for (int i=0; i<mActive.size(); i++) {
                Fragment f = mActive.get(i);
                if (f != null) {
                    moveToState(f, newState, transit, transitStyle, false);
                    if (f.mLoaderManager != null) {
                        loadersRunning |= f.mLoaderManager.hasRunningLoaders();
                    }
                }
            }

            if (!loadersRunning) {
                startPendingDeferredFragments();
            }

            if (mNeedMenuInvalidate && mHost != null && mCurState == Fragment.RESUMED) {
                mHost.onSupportInvalidateOptionsMenu();
                mNeedMenuInvalidate = false;
            }
        }
    }

moveToState的逻辑比较清晰:

  • 使用mCurState保存传入进来的状态,例如onCreate的状态是Fragment.CREATED
  • 检查mActive列表是否为空(mActive保存的是Fragment列表),如果不为空,那么遍历此列表,然后调用另一个moveToState方法。这个moveToState就是Activity管理Fragment生命周期的核心所在。

    在分析此moveToState之前,先简单介绍Fragment的状态:

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.

    int mState = INITIALIZING;

在F

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值