标签:设计模式 源码 android 开源项目 fragment
Fragment管理中,不得不谈到的就是它的事务管理,它的事务管理写的非常的出彩。我们先引入一个简单常用的Fragment事务管理代码片段:
FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction();
ft.add(R.id.fragmentContainer, fragment, "tag");
ft.addToBackStack("<span style="font-family: Arial, Helvetica, sans-serif;">tag</span><span style="font-family: Arial, Helvetica, sans-serif;">");</span>
ft.commitAllowingStateLoss();我们先来看Manager.beginTransaction这个方法的返回值:
/**
* Start a series of edit operations on the Fragments associated with this
* FragmentManager.
*
* <p>
* Note: A fragment transaction can only be created/committed prior to an
* activity saving its state. If you try to commit a transaction after
* {@link FragmentActivity#onSaveInstanceState
* FragmentActivity.onSaveInstanceState()} (and prior to a following
* {@link FragmentActivity#onStart FragmentActivity.onStart} or
* {@link FragmentActivity#onResume FragmentActivity.onResume()}, you will
* get an error. This is because the framework takes care of saving your
* current fragments in the state, and if changes are made after the state
* is saved then they will be lost.
* </p>
*/
public abstract FragmentTransaction beginTransaction();在Fragment的管理中FragmentManager的实现类是FragmentManagerImpl,当然这也是Android一贯的命名方式;
FragmentManagerImpl.java:
@Override
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
void addOp(Op op) {
if (mHead == null) {
mHead = mTail = op;
} else {
op.prev = mTail;
mTail.next = op;
mTail = op;
}
op.enterAnim = mEnterAnim;
op.exitAnim = mExitAnim;
op.popEnterAnim = mPopEnterAnim;
op.popExitAnim = mPopExitAnim;
mNumOp++;
}
public FragmentTransaction add(Fragment fragment, String tag) {
doAddOp(0, fragment, tag, OP_ADD);
return this;
}
public FragmentTransaction add(int containerViewId, Fragment fragment) {
doAddOp(containerViewId, fragment, null, OP_ADD);
return this;
}
public FragmentTransaction add(int containerViewId, Fragment fragment, String tag) {
doAddOp(containerViewId, fragment, tag, OP_ADD);
return this;
}是采用"Builder"的方式来组织。文章开始我已经提到了,Fragment的事务管理是比较出彩的代码,单纯的事务采用了至少三套模式来组织,而且组织起来丝毫没有感觉。当然Fragment带给我们的惊喜还不仅限于此。我们总上面的代码片段可以看出,实际上,通过事务类BackStackRecord生成Op对象实际上在复制BackStackRecord的属性,所以当我们分析每一个Op里面的数据的时候,可以直接用BackStackRecord中的属性映射。
int mNumOp;//Op数量
int mEnterAnim;//进入动画
int mExitAnim;//退出动画
int mPopEnterAnim;//弹出进入动画
int mPopExitAnim;//弹出退出动画
int mTransition;//转场动画
int mTransitionStyle;
boolean mAddToBackStack;//是否加入到BackStack中 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.java:
int commitInternal(boolean allowStateLoss) {
if (mCommitted) throw new IllegalStateException("commit already called");
mCommitted = true;
if (mAddToBackStack) {
mIndex = mManager.allocBackStackIndex(this);
} else {
mIndex = -1;
}
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}FragmentManager.java:
public void enqueueAction(Runnable action, boolean allowStateLoss) {
if (!allowStateLoss) {
checkStateLoss();
}
synchronized (this) {
if (mActivity == null) {
throw new IllegalStateException("Activity has been destroyed");
}
if (mPendingActions == null) {
mPendingActions = new ArrayList<Runnable>();
}
mPendingActions.add(action);
if (mPendingActions.size() == 1) {
mActivity.mHandler.removeCallbacks(mExecCommit);
mActivity.mHandler.post(mExecCommit);
}
}
}BackStackRecord.java:
Op op = mHead;
while (op != null) {
...
}Op.java:
case OP_ADD: {
Fragment f = op.fragment;
f.mNextAnim = op.enterAnim;
mManager.addFragment(f, false);
} break;FragmentManager.java:
public void addFragment(Fragment fragment, boolean moveToStateNow) {
if (mAdded == null) {
mAdded = new ArrayList<Fragment>();
}
makeActive(fragment);
if (!fragment.mDetached) {
if (mAdded.contains(fragment)) {
throw new IllegalStateException("Fragment already added: "
+ fragment);
}
mAdded.add(fragment);
fragment.mAdded = true;
fragment.mRemoving = false;
if (fragment.mHasMenu && fragment.mMenuVisible) {
mNeedMenuInvalidate = true;
}
if (moveToStateNow) {
moveToState(fragment);
}
}
}
[Android]Fragment源码分析(三) 事务,布布扣,bubuko.com
标签:设计模式 源码 android 开源项目 fragment
原文地址:http://blog.csdn.net/hello__zero/article/details/38387967