我们先看下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,但是还是写了。。。