我们先看下fragment的getContext方法:
@Nullable public Context getContext() { return mHost == null ? null : mHost.getContext(); }可以看到context是由mHost的getContext方法得到的,Ctrl+左键发现mHost是一个FragmentHostCallback类的对象,接下来就是要知道Fragment中的mHost对象是在哪里赋值的就行了。
我们的fragment一般是通过fragmentManager的beginTransaction方法得到FragmentTransaction然后add添加,而我们getSupportFragmentManager获取到的是FragmentManagerImpl,也就是FragmentManager的实现类(后面会知道),我们看FragmentManagerImpl的beginTransaction方法:
@Override public FragmentTransaction beginTransaction() { return new BackStackRecord(this); }可以看到我们得到的FragmentTransaction是一个BackStackRecord对象,该类继承自FragmnetTransaction,而BackStackRecord的add方法最终还是回到FragmentManagerImpl的addFragment方法(这其中涉及到fragment的启动过程,这里不细讲):
public void addFragment(Fragment fragment, boolean moveToStateNow) { ... if (moveToStateNow) { moveToState(fragment); } void moveToState(Fragment f) { moveToState(f, mCurState, 0, 0, false); } void moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive) { ... switch (f.mState) { case Fragment.INITIALIZING: ... f.mHost = mHost; f.mParentFragment = mParent; f.mFragmentManager = mParent != null ? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl(); ... } }可以看到 f.mHost = mHost ,也就是fragment中获取context时使用的FragmentHostCallback类的对象mHost是由FragmentManagerImpl赋值的。
那我们的问题就变成了:它的mHost哪里来的?
我们看到fragmentManagerImpl的attachController方法:
public void attachController(FragmentHostCallback host, FragmentContainer container, Fragment parent) { if (mHost != null) throw new IllegalStateException("Already attached"); mHost = host; mContainer = container; mParent = parent; }mHost是在这里赋值,该方法由FragmentController调用:
public void attachHost(Fragment parent) { mHost.mFragmentManager.attachController( mHost, mHost /*container*/, parent); }那fragmentController是谁?它的mHost是哪里来的?
我们添加Fragment一般是通过getSupportFragmentManager().beginTransaction()得到一个FragmentTransaction对象,我们看一下FragmentActivity中的getSupportFragmentManager方法:
final FragmentController mFragments = FragmentController.createController(new HostCallbacks()); ... public FragmentManager getSupportFragmentManager() { return mFragments.getSupportFragmentManager(); }可以看到Activity是通过一个final类型的FragmentController对象的getSupportFragmentManager来获取fragmentManager的
public class FragmentController { private final FragmentHostCallback<?> mHost; /** * Returns a {@link FragmentController}. */ public static 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的getSupportFragmentManager是通过构造函数的参数FragmentHostCallback对象的getFragmentMnaagerIml得到:
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(); ... FragmentManagerImpl getFragmentManagerImpl() { return mFragmentManager; } }直接返回一个FragmentManagerImpl,它继承自FragmentManager。
原来fragmentManager和其mHost对象都是由FragmentActivity中的fragmentController对象得到,
到这里我们的问题变成了:FragmentController中的mHost是哪来的?
就是FragmentActivity传入的:
final FragmentController mFragments = FragmentController.createController(new HostCallbacks()); LoaderManager mLoaderManager;我们看一下HostCallbacks:
class HostCallbacks extends FragmentHostCallback<FragmentActivity> { public HostCallbacks() { super(FragmentActivity.this /*fragmentActivity*/); } }可以看到HostCallbacks持有一个当前的activity对象,调用FragmentHostCallback的构造函数:
public FragmentHostCallback(Context context, Handler handler, int windowAnimations) { this(context instanceof Activity ? (Activity) context : null, context, handler, windowAnimations); } FragmentHostCallback(FragmentActivity activity) { this(activity, activity /*context*/, activity.mHandler, 0 /*windowAnimations*/); } FragmentHostCallback(Activity activity, Context context, Handler handler, int windowAnimations) { mActivity = activity; mContext = context; mHandler = handler; mWindowAnimations = windowAnimations; }一切都付出水面了,mHost中的context在这里。
总结一下:
FragmentActivity有一个final类型的FragmentController对象,FragmentController持有HostCallback对象mHost(mHost持有context),然后FragmentManager也是由该mHost创建并在FragmentController调用其attachController方法时候为其mHost赋值(FragmentManager的mHost和FragmentController的mHost是同一个),Fragment中的mHost在add的时候被FragmentManager赋值。
其实一切的来源都是FragmentActivity持有的FragmentController对象!
虽然可能用脚指头想都能想到fragment的getContext方法获取的就是其附着的Activity,但是还是写了。。。
喜欢点个赞!!