Fragment源码解析

一、Fragment的简单使用:

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.radio1, tabFourFragment, tabFourFragment.getTag());
transaction.remove(tabFourFragment);
transaction.replace(R.id.radio1, tabFourFragment);
transaction.addToBackStack(tabFourFragment.getTag());
transaction.commit();

主要涉及到的类如下图所示:
这里写图片描述

通过FragmentActivity来获取FragmentManager,FragmentActivity内部有一个FragmentController对象mFragments,它看起来像是其内部类HostCallBack(继承自FragmentHostCallback)的代理类,代理HostCallback处理众多回调事件;
HostCallBack持有FragmentManager(实际类型为FragmentManagerImpl)对象,用户通过getFragmentManager获取到的即为该对象;
调用FragmentManagerImpl的beginTransaction返回的是一个FragmentTransaction(实际类型为BackStackRecord,它是一个Runnbale),后面的一切add,replace等事务处理操作,都是BackStackRecord创建一个特定类型的Op(Op是一个记录操作事务事件类型的双向链表),然后添加到事件队列中,每一个add等事件对应一个Op;然后在commit时统一通过FragmentManager进行处理,处理的关键函数为moveToState。

二、来看FragmentTransaction的实际类型:

* FragmentActivity#getSupportFragmentManager: *

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

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

HostCallbacks主要实现了像onAttachFragment、onStartActivityFromFragment、onFindViewById等回调方法,并且持有FragmentActivity的Activity、Context、Handler等引用,并且为它所持有的FragmentManager提供资源。
FragmentController负责将生命周期分发给它持有的FragmentHostCallback中的FragmentManager。

1、HostCallbacks:

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

    @Override
    public void onDump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
        FragmentActivity.this.dump(prefix, fd, writer, args);
    }

    .......

    @Override
    public boolean onHasWindowAnimations() {
        return getWindow() != null;
    }

    @Override
    public int onGetWindowAnimations() {
        final Window w = getWindow();
        return (w == null) ? 0 : w.getAttributes().windowAnimations;
    }

    @Override
    public void onAttachFragment(Fragment fragment) {
        FragmentActivity.this.onAttachFragment(fragment);
    }

    @Nullable
    @Override
    public View onFindViewById(int id) {
        return FragmentActivity.this.findViewById(id);
    }

    @Override
    public boolean onHasView() {
        final Window w = getWindow();
        return (w != null && w.peekDecorView() != null);
    }
}

继续来看FragmentHostCallback:

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 SimpleArrayMap<String, LoaderManager> mAllLoaderManagers;
    private LoaderManagerImpl mLoaderManager;
    private boolean mCheckedForLoaderManager;
    private boolean mLoadersStarted;

    public FragmentHostCallback(Context context, Handler handler, int windowAnimations) {
        this(null, context, handler, windowAnimations);
    }

    // 传入进来的构造函数
    FragmentHostCallback(FragmentActivity activity) {
        this(activity, activity , activity.mHandler, 0);
    }

    FragmentHostCallback(Activity activity, Context context, Handler handler,
                         int windowAnimations) {
        mActivity = activity;
        mContext = context;
        mHandler = handler;
        mWindowAnimations = windowAnimations;
    }

    FragmentManagerImpl getFragmentManagerImpl() {
        return mFragmentManager;
    }
}

可以看到 FragmentHostCallback持有FragmentActivity的activity,Handler,Context的引用,并且创建一个FragmentManagerImpl,它是FragmentManager的具体实现类,这是Android常见的用法。

2、FragmentController#createController:

public class FragmentController {
   
   
    private final FragmentHostCallback<?> mHost;

    /**
     * Returns a {@link FragmentController}.
     */
    public static final FragmentController createController(FragmentHostCallback<?> callbacks) {
        return new FragmentController(callbacks);
    }

    private FragmentController(FragmentHostCallback<?> callbacks) {
        mHost = callbacks;
    }

    /**
     * Returns a {@link FragmentManager} for this controller.
     */
    public FragmentManager getSupportFragmentManager() {
        return mHost.getFragmentManagerImpl();
    }
    .......
}

可以看到FragmentController提供的很多方法都是通过FragmentHostCallback来实现的,而之前调用getSupportFragmentManager获取到的也就是在HostCallback中创建的FragmentManagerImpl对象;
下面调用

3、FragmentManagerImpl#beginTransaction:

@Override
public FragmentTransaction beginTransaction() {
    return new BackStackRecord(this);
}

4、BackStackRecord:

final class BackStackRecord extends FragmentTransaction implements
        FragmentManager.BackStackEntry, Runnable {

    final FragmentManagerImpl mManager;

    public BackStackRecord(FragmentManagerImpl manager) {
        mManager = manager;
    }
}

BackStackRecord是FragmentTransaction的具体实现类,从名称可以看出,它是用来记录BackStack的;而且它集成了Runnable,是一个线程;后面的一系列操作也是基于该类来实现的;
故综上所述:FragmentTransaction的实际类型为BackStackRecord;

三、接下来看FragmentTransaction的操作:

1、BackStackRecord#add:

public FragmentTransaction add(int containerViewId, Fragment fragment, String tag) {
    // 注意传入的动作类型对应为OP_ADD
    doAddOp(containerViewId, fragment, tag, OP_ADD);
    return this;
}

private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
    fragment.mFragmentManager = mManager;

    // 设置fragment的tag
    if (tag != null) {
        // 如果fragment的mTag已经设置
        if (fragment.mTag != null && !tag.equals(fragment.mTag)) {
            throw new IllegalStateException("Can't change tag of fragment "
                    + fragment + ": was " + fragment.mTag
                    + " now " + tag);
        }
        fragment.mTag = tag;
    }

    // 设置fragment的ContainerId 
    if (containerViewId != 0) {
        if (fragment.mFragmentId != 0 && fragment.mFragmentId != containerViewId) {
            throw new IllegalStateException("Can't change container ID of fragment "
                    + fragment + ": was " + fragment.mFragmentId
                    + " now " + containerViewId);
        }
        fragment.mContainerId = fragment.mFragmentId = containerViewId;
    }

    // 重要类Op,主要的操作都是基于此的
    Op op = new Op();
    op.cmd = opcmd;
    op.fragment = fragment;
    addOp(op);
}

上面涉及到简单的fragment赋值操作,最重要的引出了一个Op类,FragmentTransaction的所有操作都是基于此来实现的。

2、Op:

final class BackStackRecord extends FragmentTransaction implements
        FragmentManager.BackStackEntry, Runnable {
    // 对应Transaction的各种操作
    static final int OP_NULL = 0;
    static final int OP_ADD = 1;
    static final int OP_REPLACE = 2;
    static final int OP_REMOVE = 3;
    static final int OP_HIDE = 4;
    static final int OP_SHOW = 5;
    static final int OP_DETACH = 6;
    static final int OP_ATTACH = 7;

    // BackStackRecord的静态内部类
    static final class Op {
        // 明显的双向链表结构
        Op next;
        Op prev;
        // 执行操作类型
        int cmd;
        // 执行的fragment
        Fragment fragment;
        int enterAnim;
        int exitAnim;
        int popEnterAnim;
        int popExitAnim;
        ArrayList<Fragment> removed;
    }

    // Op链表的头节点和尾节点
    Op mHead;
    Op mTail;
}

Op是 BackStackRecord 的静态内部类,是个明显的双向链表结构,其中保存了操作的Fragment引用及操作类型;一个add事件,会创建一个Op对象与之对应,并且调用addOp操作。

3、BackStackRecord#addOp:

// 记录op的总数目
int mNumOp;

// 双向链表的插入操作
void addOp(Op op) {
    if<
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值