一、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<