热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

通常情况下我们使用fragment的方式是这样的:FragmentManagermFragmentManagergetFragmentManager();Fragme

通常情况下我们使用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 &#61;&#61; null || mAvailBackStackIndices.size() <&#61; 0) {

if (mBackStackIndices &#61;&#61; null) {

mBackStackIndices &#61; new ArrayList();

}

int index &#61; mBackStackIndices.size();

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

mBackStackIndices.add(bse);

return index;

} else {

int index &#61; mAvailBackStackIndices.remove(mAvailBackStackIndices.size()-1);

if (DEBUG) Log.v(TAG, "Adding back stack index " &#43; index &#43; " with " &#43; 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() &#61;&#61; 1) {

mHost.getHandler().removeCallbacks(mExecCommit);

mHost.getHandler().post(mExecCommit);

}

}

}

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

// FragmentManagerImpl.java

Runnable mExecCommit &#61; new Runnable() {

&#64;Override

public void run() {

execPendingActions();

}

};

public boolean execPendingActions() {

while (true) {

int numActions;

synchronized (this) {

numActions &#61; mPendingActions.size();

if (mTmpActions &#61;&#61; null || mTmpActions.length

mTmpActions &#61; new Runnable[numActions];

}

mPendingActions.toArray(mTmpActions);

mPendingActions.clear();

mHost.getHandler().removeCallbacks(mExecCommit);

}

mExecutingActions &#61; true;

for (int i&#61;0; i

mTmpActions[i].run();

mTmpActions[i] &#61; null;

}

mExecutingActions &#61; false;

didSomething &#61; true;

}

doPendingDeferredStart();

return didSomething;

}

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

// BackStackRecord.java

public void run() {

//代码省略

Op op &#61; mHead;

while (op !&#61; null) {

switch (op.cmd) {

case OP_ADD: {

Fragment f &#61; op.fragment;

f.mNextAnim &#61; op.enterAnim;

mManager.addFragment(f, false);

}

break;

case OP_REPLACE: {

Fragment f &#61; op.fragment;

int containerId &#61; f.mContainerId;

if (mManager.mAdded !&#61; null) {

for (int i &#61; mManager.mAdded.size() - 1; i >&#61; 0; i--) {

Fragment old &#61; mManager.mAdded.get(i);

if (FragmentManagerImpl.DEBUG) {

Log.v(TAG,

"OP_REPLACE: adding&#61;" &#43; f &#43; " old&#61;" &#43; old);

}

if (old.mContainerId &#61;&#61; containerId) {

if (old &#61;&#61; f) {

op.fragment &#61; f &#61; null;

} else {

if (op.removed &#61;&#61; null) {

op.removed &#61; new ArrayList();

}

op.removed.add(old);

old.mNextAnim &#61; op.exitAnim;

if (mAddToBackStack) {

old.mBackStackNesting &#43;&#61; 1;

if (FragmentManagerImpl.DEBUG) {

Log.v(TAG, "Bump nesting of "

&#43; old &#43; " to " &#43; old.mBackStackNesting);

}

}

mManager.removeFragment(old, mTransition, mTransitionStyle);

}

}

}

}

if (f !&#61; null) {

f.mNextAnim &#61; op.enterAnim;

mManager.addFragment(f, false);

}

}

break;

// 代码省略

}

op &#61; op.next;

}

mManager.moveToState(mManager.mCurState, mTransition,

mTransitionStyle, true);

if (mAddToBackStack) {

mManager.addBackStackState(this);

}

}

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

public void addFragment(Fragment fragment, boolean moveToStateNow) {

makeActive(fragment);

if (!fragment.mDetached) {

if (mAdded.contains(fragment)) {

throw new IllegalStateException("Fragment already added: " &#43; fragment);

}

mAdded.add(fragment);

fragment.mAdded &#61; true;

fragment.mRemoving &#61; false;

if (fragment.mHasMenu && fragment.mMenuVisible) {

mNeedMenuInvalidate &#61; true;

}

if (moveToStateNow) {

moveToState(fragment);

}

}

}

void moveToState(Fragment f) {

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

}

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

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 &#61; Fragment.CREATED;

}

if (f.mFromLayout) {

// fragment的onCreateView方法

f.mView &#61; f.performCreateView(f.getLayoutInflater(

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

if (f.mView !&#61; null) {

f.mView.setSaveFromParentEnabled(false);

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

// fragment的onViewCreated方法

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

}

}

//代码省略

}



推荐阅读
author-avatar
手浪用户2602925023
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有