Fragment总结——源码个人分析

    xiaoxiao2022-07-04  138

    上次说到了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来进行配合使用的。

    最新回复(0)