上次说到了Fragment,还没有补源码解析,今天有空,在AS中写了一个Fragment,Ctrl点进去看看源码,总结总结。
这里我先从最初的Fragment开始看。
ComponentCallbacks是android.content.res.Configuration目录下的一个接口,里面定义了两个方法,Android四大组件都实现了这个接口.它有两个方法分别是用来实时更新设备资源配置的,另外一个是释放资源方便GC的。
OnCreateContextMenuListener接口是用来处理上下文菜单显示事件的监听接口。他只有一个方法,当某个View中显示上下文菜单时被调用,开发人员可以通过实现该方法来处理上下文菜单显示时的一些操作。
LifecycleOwner是Lifecycle 对象的持有者,它有一个方法就是获取Lifecycle对象。在Fragment中就是创建了一个LifecycleRegistry的对象,它是LifecycleRegistry的实现子类。
ViewModelStoreOwner是ViewModelStore对象的持有者,它有一个方法就是获取ViewModelStore对象。它的职责是在配置更改期间保留拥有的ViewModelStore。
private static final SimpleArrayMap<String, Class<?>> sClassMap = new SimpleArrayMap();
static final Object USE_DEFAULT_TRANSITION = new Object();
static final int INITIALIZING = 0;
static final int CREATED = 1;
static final int ACTIVITY_CREATED = 2;
static final int STARTED = 3;
static final int RESUMED = 4;
int mState = 0;
Bundle mSavedFragmentState;
SparseArray<Parcelable> mSavedViewState;
@Nullable
Boolean mSavedUserVisibleHint;
int mIndex = -1;
String mWho;
Bundle mArguments;
Fragment mTarget;
int mTargetIndex = -1;
int mTargetRequestCode;
boolean mAdded;
boolean mRemoving;
boolean mFromLayout;
boolean mInLayout;
boolean mRestored;
boolean mPerformedCreateView;
int mBackStackNesting;
FragmentManagerImpl mFragmentManager;
FragmentHostCallback mHost;
FragmentManagerImpl mChildFragmentManager;
FragmentManagerNonConfig mChildNonConfig;
ViewModelStore mViewModelStore;
Fragment mParentFragment;
int mFragmentId;
int mContainerId;
String mTag;
boolean mHidden;
boolean mDetached;
boolean mRetainInstance;
boolean mRetaining;
boolean mHasMenu;
boolean mMenuVisible = true;
boolean mCalled;
ViewGroup mContainer;
View mView;
View mInnerView;
boolean mDeferStart;
boolean mUserVisibleHint = true;
Fragment.AnimationInfo mAnimationInfo;
boolean mIsNewlyAdded;
boolean mHiddenChanged;
float mPostponedAlpha;
LayoutInflater mLayoutInflater;
boolean mIsCreated;
LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
LifecycleRegistry mViewLifecycleRegistry;
LifecycleOwner mViewLifecycleOwner;
MutableLiveData<LifecycleOwner> mViewLifecycleOwnerLiveData = new MutableLiveData();
在Fragment里面创建了很多对象,有生命周期状态对象,ViewModleStore对象等等。接下来重点介绍一下下面几个类
从这儿就此开始介绍Fragment内部情况。
1.FragmentManagerImpl类
前者的mFragmentManager对象就是FragmentManagerImpl类型的。这个类是FragmentManager的子类。下面贴张图了解一下
这是他们之间的联系,其中最重要的联系红色字体标记的。
在FragmentHostCallback中有一个抽象方法onGetHost(),它在FragmentActivity(后面叫FMA)的内部类HostCallBacks中得到了实现,他的返回值是FMA本身,而FMA是继承于SupportActivity,SupportActivity又是继承Activity,所以追踪到底就有了Context上下文,那么如果说在Fragment中创建了FragmentHostCallback这个对象=,那么就意味着fragment获取了Context。对的,开发Fragment的人也想到了,所以他这么写的
public abstract class FragmentHostCallback<E> extends FragmentContainer{
@Nullable
private final Activity mActivity;
@NonNull
private final Context mContext;
@NonNull
private final Handler mHandler;
...
@Nullable
public abstract E onGetHost();
...
@Nullable
public View onFindViewById(int id) {
return null;
}
...
@Nullable
Activity getActivity() {
return this.mActivity;
}
@NonNull
Context getContext() {
return this.mContext;
}
@NonNull
Handler getHandler() {
return this.mHandler;
}
}
public class FragmentActivity extends SupportActivity implements ViewModelStoreOwner, OnRequestPermissionsResultCallback, RequestPermissionsRequestCodeValidator {
...
class HostCallbacks extends FragmentHostCallback<FragmentActivity> {
...
public FragmentActivity onGetHost() {
return FragmentActivity.this;
}
...
@Nullable
public View onFindViewById(int id) {
return FragmentActivity.this.findViewById(id);
}
...
}
...
}
public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner, ViewModelStoreOwner {
...
FragmentHostCallback mHost;
..
@Nullable
public Context getContext() {
return this.mHost == null ? null : this.mHost.getContext();
}
...
@Nullable
public final FragmentActivity getActivity() {
return this.mHost == null ? null : (FragmentActivity)this.mHost.getActivity();
}
...
@Nullable
public final Object getHost() {
return this.mHost == null ? null : this.mHost.onGetHost();
}
...
}
在Activity中可以获取到FragmentManager对象了,因为FragmentActivity中又获取FragmentManager对象,而Activity又继承了FragmentActivity,所以大功告成。在FragmentManager中又一个获取了一个FragmentTransaction对象,这个对象就是实质上用来添加fragment和删除fragment的最终存储集合。但Fragmenttransaction是一个抽象类,最终实现是用BackStackRecord子类来完成的,所以稍微看一看以下的代码。
FragmentManagerImpl.class
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
public int allocBackStackIndex(BackStackRecord bse) {
synchronized(this) {
int index;
if (this.mAvailBackStackIndices != null && this.mAvailBackStackIndices.size() > 0) {
index = (Integer)this.mAvailBackStackIndices.remove(this.mAvailBackStackIndices.size() - 1);
if (DEBUG) {
Log.v("FragmentManager", "Adding back stack index " + index + " with " + bse);
}
this.mBackStackIndices.set(index, bse);
return index;
} else {
if (this.mBackStackIndices == null) {
this.mBackStackIndices = new ArrayList();
}
index = this.mBackStackIndices.size();
if (DEBUG) {
Log.v("FragmentManager", "Setting back stack index " + index + " to " + bse);
}
this.mBackStackIndices.add(bse);
return index;
}
}
}
FragmentHostCallback.class
final FragmentManagerImpl mFragmentManager;
FragmentHostCallback(@Nullable Activity activity, @NonNull Context context, @NonNull Handler handler, int windowAnimations) {
this.mFragmentManager = new FragmentManagerImpl();
this.mActivity = activity;
this.mContext = (Context)Preconditions.checkNotNull(context, "context == null");
this.mHandler = (Handler)Preconditions.checkNotNull(handler, "handler == null");
this.mWindowAnimations = windowAnimations;
}
BackStackRecord.class
ArrayList<BackStackRecord.Op> mOps = new ArrayList();
public BackStackRecord(FragmentManagerImpl manager) {
this.mManager = manager;
}
public FragmentTransaction add(Fragment fragment, @Nullable String tag) {
this.doAddOp(0, fragment, tag, 1);
return this;
}
public FragmentTransaction add(int containerViewId, Fragment fragment) {
this.doAddOp(containerViewId, fragment, (String)null, 1);
return this;
}
public FragmentTransaction add(int containerViewId, Fragment fragment, @Nullable String tag) {
this.doAddOp(containerViewId, fragment, tag, 1);
return this;
}
private void doAddOp(int containerViewId, Fragment fragment, @Nullable String tag, int opcmd) {
Class fragmentClass = fragment.getClass();
int modifiers = fragmentClass.getModifiers();
if (fragmentClass.isAnonymousClass() || !Modifier.isPublic(modifiers) || fragmentClass.isMemberClass() && !Modifier.isStatic(modifiers)) {
throw new IllegalStateException("Fragment " + fragmentClass.getCanonicalName() + " must be a public static class to be properly recreated from" + " instance state.");
} else {
fragment.mFragmentManager = this.mManager;
if (tag != null) {
if (fragment.mTag != null && !tag.equals(fragment.mTag)) {
throw new IllegalStateException("Can't change tag of fragment " + fragment + ": was " + fragment.mTag + " now " + tag);
}
fragment.mTag = tag;
}
if (containerViewId != 0) {
if (containerViewId == -1) {
throw new IllegalArgumentException("Can't add fragment " + fragment + " with tag " + tag + " to container view with no id");
}
if (fragment.mFragmentId != 0 && fragment.mFragmentId != containerViewId) {
throw new IllegalStateException("Can't change container ID of fragment " + fragment + ": was " + fragment.mFragmentId + " now " + containerViewId);
}
fragment.mContainerId = fragment.mFragmentId = containerViewId;
}
this.addOp(new BackStackRecord.Op(opcmd, fragment));
}
}
public int commit() {
return this.commitInternal(false);
}
int commitInternal(boolean allowStateLoss) {
if (this.mCommitted) {
throw new IllegalStateException("commit already called");
} else {
if (FragmentManagerImpl.DEBUG) {
Log.v("FragmentManager", "Commit: " + this);
LogWriter logw = new LogWriter("FragmentManager");
PrintWriter pw = new PrintWriter(logw);
this.dump(" ", (FileDescriptor)null, pw, (String[])null);
pw.close();
}
this.mCommitted = true;
if (this.mAddToBackStack) {
this.mIndex = this.mManager.allocBackStackIndex(this);
} else {
this.mIndex = -1;
}
this.mManager.enqueueAction(this, allowStateLoss);
return this.mIndex;
}
}
总结一下,就是在Fragment中会创建很多关于生命周期,获取状态,存储数据的对象,以及他们的初始化,其中fragmentActivity是用来获取上下文以及拿到生命周期,以方便后续的方法调用和数据保存(他是通过FragmentHostCallback过渡进行数据绑定获取的)。BackStackRecord是进行动态添加删除提交Fragment的实现类,他也是需要FragmentManagerImpl来进行配合使用的。