android.fragment源码,【Android源码】Fragment 源码分析

通常情况下我们使用fragment的方式是这样的:

FragmentManager mFragmentManager = getFragmentManager();

FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();

fragmentTransaction.add(mContainerViewId, fragment);

fragmentTransaction.commit();

那么Fragment是如果创建的,如何被添加到布局中的呢,我们一起来分析下系统是如何做的。

通过点击add、beginTransaction可以发现都是抽象方法,那么只能通过getFragmentManager()首先获得 FragmentManager:

public FragmentManager getFragmentManager() {

return mFragments.getFragmentManager();

}

final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();

最终可以获得FragmentManagerImpl这个FragmentMananger实现类。

// FragmentManagerImpl.java

@Override

public FragmentTransaction beginTransaction() {

return new BackStackRecord(this);

}

// BackStackRecord.java

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;

}

最终通过调用BackStackRecord的doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd)方法将fragment加入管理中。

private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {

fragment.mFragmentManager = mManager;

Op op = new Op();

op.cmd = opcmd;

op.fragment = fragment;

addOp(op);

}

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++;

}

可以发现在add方法中,系统只做了赋值操作,并没有对fragment进行任何操作,所以应该是在commit中进行操作的:

// BackStackRecord.java

public int commit() {

return commitInternal(false);

}

int commitInternal(boolean allowStateLoss) {

if (mCommitted) {

throw new IllegalStateException("commit already called");

}

if (FragmentManagerImpl.DEBUG) {

Log.v(TAG, "Commit: " + this);

LogWriter logw = new LogWriter(Log.VERBOSE, TAG);

PrintWriter pw = new FastPrintWriter(logw, false, 1024);

dump(" ", null, pw, null);

pw.flush();

}

mCommitted = true;

if (mAddToBackStack) {

mIndex = mManager.allocBackStackIndex(this);

} else {

mIndex = -1;

}

mManager.enqueueAction(this, allowStateLoss);

return mIndex;

}

// FragmentManager.java

public int allocBackStackIndex(BackStackRecord bse) {

synchronized (this) {

if (mAvailBackStackIndices == null || mAvailBackStackIndices.size() <= 0) {

if (mBackStackIndices == null) {

mBackStackIndices = new ArrayList();

}

int index = mBackStackIndices.size();

if (DEBUG) Log.v(TAG, "Setting back stack index " + index + " to " + bse);

mBackStackIndices.add(bse);

return index;

} else {

int index = mAvailBackStackIndices.remove(mAvailBackStackIndices.size()-1);

if (DEBUG) Log.v(TAG, "Adding back stack index " + index + " with " + bse);

mBackStackIndices.set(index, bse);

return index;

}

}

}

public void enqueueAction(Runnable action, boolean allowStateLoss) {

if (!allowStateLoss) {

checkStateLoss();

}

synchronized (this) {

mPendingActions.add(action);

if (mPendingActions.size() == 1) {

mHost.getHandler().removeCallbacks(mExecCommit);

mHost.getHandler().post(mExecCommit);

}

}

}

commit方法最终调用了manager的allocBackStackIndex和enqueueAction方法,其中allocBackStackIndex方法将BackStackRecord添加到了mBackStackIndices中,而enqueueAction方法首先将实现了Runnable的BackStackRecord添加到了mPendingActions,之后调用了handler。

// FragmentManagerImpl.java

Runnable mExecCommit = new Runnable() {

@Override

public void run() {

execPendingActions();

}

};

public boolean execPendingActions() {

while (true) {

int numActions;

synchronized (this) {

numActions = mPendingActions.size();

if (mTmpActions == null || mTmpActions.length < numActions) {

mTmpActions = new Runnable[numActions];

}

mPendingActions.toArray(mTmpActions);

mPendingActions.clear();

mHost.getHandler().removeCallbacks(mExecCommit);

}

mExecutingActions = true;

for (int i=0; i

mTmpActions[i].run();

mTmpActions[i] = null;

}

mExecutingActions = false;

didSomething = true;

}

doPendingDeferredStart();

return didSomething;

}

execPendingActions方法首先将mPendingActions赋值给了mTmpActions,之后通过for循环调用run方法:

// BackStackRecord.java

public void run() {

//代码省略

Op op = mHead;

while (op != null) {

switch (op.cmd) {

case OP_ADD: {

Fragment f = op.fragment;

f.mNextAnim = op.enterAnim;

mManager.addFragment(f, false);

}

break;

case OP_REPLACE: {

Fragment f = op.fragment;

int containerId = f.mContainerId;

if (mManager.mAdded != null) {

for (int i = mManager.mAdded.size() - 1; i >= 0; i--) {

Fragment old = mManager.mAdded.get(i);

if (FragmentManagerImpl.DEBUG) {

Log.v(TAG,

"OP_REPLACE: adding=" + f + " old=" + old);

}

if (old.mContainerId == containerId) {

if (old == f) {

op.fragment = f = null;

} else {

if (op.removed == null) {

op.removed = new ArrayList();

}

op.removed.add(old);

old.mNextAnim = op.exitAnim;

if (mAddToBackStack) {

old.mBackStackNesting += 1;

if (FragmentManagerImpl.DEBUG) {

Log.v(TAG, "Bump nesting of "

+ old + " to " + old.mBackStackNesting);

}

}

mManager.removeFragment(old, mTransition, mTransitionStyle);

}

}

}

}

if (f != null) {

f.mNextAnim = op.enterAnim;

mManager.addFragment(f, false);

}

}

break;

// 代码省略

}

op = op.next;

}

mManager.moveToState(mManager.mCurState, mTransition,

mTransitionStyle, true);

if (mAddToBackStack) {

mManager.addBackStackState(this);

}

}

这个时候就用上了我们之前add方法的opcmd字段,add赋值的字段是OP_ADD,所以可以看到直接调用了mManager.addFragment(f, false)方法;而replace方法赋值的字段是OP_REPLACE,首先调用mManager.removeFragment(old, mTransition, mTransitionStyle)方法将上一个fragment移除,之后再调用mManager.addFragment(f, false):

public void addFragment(Fragment fragment, boolean moveToStateNow) {

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);

}

}

}

void moveToState(Fragment f) {

moveToState(f, mCurState, 0, 0, false);

}

这个时候调用的moveToState方法就涉及到了Fragment的生命周期:

void moveToState(Fragment f, int newState, int transit, int transitionStyle,

boolean keepActive) {

switch (f.mState) {

case Fragment.INITIALIZING:

// fragment的onAttach方法

f.onAttach(mHost.getContext());

if (!f.mRetaining) {

// fragment的onCreate方法

f.performCreate(f.mSavedFragmentState);

} else {

f.restoreChildFragmentState(f.mSavedFragmentState, true);

f.mState = Fragment.CREATED;

}

if (f.mFromLayout) {

// fragment的onCreateView方法

f.mView = f.performCreateView(f.getLayoutInflater(

f.mSavedFragmentState), null, f.mSavedFragmentState);

if (f.mView != null) {

f.mView.setSaveFromParentEnabled(false);

if (f.mHidden) f.mView.setVisibility(View.GONE);

// fragment的onViewCreated方法

f.onViewCreated(f.mView, f.mSavedFragmentState);

}

}

//代码省略

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值