Fragment源码解析(一): Activity与 FragmentManager是如何关联的呢?

3,223 阅读4分钟

Fragment 源码解析(二):FragmentManager 生命周期

在平时的开发过程中, Fragment 是我们使用频率非常高的组件, 它可以让我们在 Activity 中更加灵活的实现多个界面的功能, 这在某些场景下是非常有用的, 尤其是大屏设备上, 比如 pad 端,车载等.

平时大家在使用 Fragment 的时候, 都是从下面的代码开始:

getSupportFragmentManager()       
         .beginTransaction()       
         ...

那么 FragmentManager 是什么呢? 它跟 Activity 之间的关系又是什么呢? 这篇文章将从源码的角度去解析 FragmentManager 与 Activity 之间是如何关联的.

1.是什么?

从字面意思来看, FragmentManager 就是 Fragment 的管理类, 点开源码可以看到也确实是这样, Fragment 的生命周期就是通过 FragmentManager 来管理的. 

查看源码可以看到 FragmentManager是一个抽象类, 它的实现类是 FragmentManagerImpl 类,

2.跟 Activity 的关联关系?

要想弄清楚 FragmentManager 跟 activity 跟 Activity 之间的关系, 我们就要去 Activity 中去查看一下, 这里直接去看 FragmentActivity 的内部源码.

在 FragmentActivity 内部有这样一行代码:

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

FragmentActivity 内部定义了一个 FragmentController 全局变量, 并 new 了一个 HostCallbacks 对象作为参数传入. 首先我们看看FragmentController 是个什么东西, 他的内部又做了哪些操作呢?

点击进入 createController()方法可以看到在该方法中 new 了一个FragmentController对象并将传递进来的对象FragmentHostCallback赋值给内部的

 mHost.

列举一下该类的内部实现方法:




等等等等...

其实可以看到, 该类并没有做什么实质性的操作, 真正的操作都是通过 mHost 里面的 mFragmentManager 代理出去了, 在这里我们竟然发现了 FragmentManager 的踪影, 那 mHost 有是什么呢?

在前面我们看到过, mHost 是通过 FragmentController 的构造方法赋值的, FragmentController 的createController()方法在内部 new 了一个 FragmentController 对象, 而 createController 又是在 FragmetnActivity 中调用了:

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

而 mHost 正是这个 HostCallback对象!

HostCallback是 FragmentActivity 的一个内部类, 他继承自FragmentHostCallback, 点击进入 FragmentHostCallback 发现其内部定义了一个 FragmentManager 的实现类 FragmentManagerImpl:

final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();

而 HostCallback 相当于 FragmentManager 在 FragmentActivity 内的回调类

至此, 整体的一个逻辑基本就清除了:

  1. activity 在初始化的时候, 先创建了一个 FragmentHostCallback对象;
  2. FragmentHostCallback 对象在创建的时候在内部创建了一个 FragmentManagerImpl;
  3. activity 内部定义一个 FragmentController 变量, 并将 FragmentHostCallback 传递给 FragmentController 内部;
  4. 在 createController 时创建了一个 FragmentHostCallback 对象

接下来就是当 activity 要对 Fragment进行操作时, 都会通过 FragmentController 对象即 FragmentActivity内部的 fragments来操作, fragments 内部没有做什么实质性的内容, 都是通过 mHost 内部的 fragmentManager 来操作, 这样就把实际操作的行为交给了 FragmentManager.

在文章刚开始的时候说过, 使用 Fragment 都是从 getSupportFragment()这个方法开始的, 那我们看看这个方法里面做了什么事情:

public FragmentManager getSupportFragmentManager() {    
    return this.mFragments.getSupportFragmentManager();
}

这里的 this.mFragments 指的就是 FragmentActivity 中的变量 FragmentController, 再看看这个方法的内部:

public FragmentManager getSupportFragmentManager() {    
    return this.mHost.getFragmentManagerImpl();
}

而 mHost 就是在 FragmentActivity 创建的时候创建来的 FragmentHostCallback

前面讲到 FragmentHostCallback 内部就直接 new 了一个 FragmentManagerImpl 对象

这样我们就可以得到下面的关联关系:


并且我们也可以得出这样的结论:

一个 Activity 只对应一个 FragmentManager 对象

现在我们知道了, Activity 的 FragmentManager 对象是在 Activity 初始化的时候创建的, 那我们的 activity 是在什么时候初始化的呢? 这个就涉及到了 Activity 的启动过程, 这个不是我们的重点, 简单的说一下activity 初始化的过程:

 1.当我们调用 startactivity()启动一个 activity 的时候, 会调用到 ActivityThread 中的 performLaunchActivity()方法

2.performLaunchActivity()方法内部会调用 mInstrumentation.newActivity() 方法

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ....
    activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
    ....
}

3.在 newActivity()方法内部会调用 真正的去初值化 activity:

Activity activity = (Activity)clazz.newInstance();

至此, FragmentManager 与 Activity 的 关联过程我们就分析完了

下一篇文章, 将会通过源码的角度分析一下 FragmentManager 的生命周期, 是的你没有看错, 就是 FragmentManager 的生命周期!