@RitcheeQinG
2020-09-07T02:12:33.000000Z
字数 2664
阅读 441
Android
FragmentActivity
@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {mFragments.attachHost(null /*parent*/);if (savedInstanceState != null) {Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);mFragments.restoreSaveState(p);// ...}}
这里的 mFragments 是 FragmentController
/*** Restores the saved state for all Fragments.** @param state the saved state containing the Parcelable returned by {@link #saveAllState()}* @see #saveAllState()*/public void restoreSaveState(@Nullable Parcelable state) {if (!(mHost instanceof ViewModelStoreOwner)) {throw new IllegalStateException("Your FragmentHostCallback must implement "+ "ViewModelStoreOwner to call restoreSaveState(). Call restoreAllState() "+ " if you're still using retainNestedNonConfig().");}mHost.mFragmentManager.restoreSaveState(state);}
FragmentManagerImpl
void restoreSaveState(Parcelable state) {// ... 主要看这里// Build the full list of active fragments, instantiating them from// their saved state.mActive.clear();for (FragmentState fs : fms.mActive) {if (fs != null) {Fragment f = fs.instantiate(mHost.getContext().getClassLoader(),getFragmentFactory());f.mFragmentManager = this;if (DEBUG) Log.v(TAG, "restoreSaveState: active (" + f.mWho + "): " + f);mActive.put(f.mWho, f);// Now that the fragment is instantiated (or came from being// retained above), clear mInstance in case we end up re-restoring// from this FragmentState again.fs.mInstance = null;}}// ...}
FragmentState
public Fragment instantiate(@NonNull ClassLoader classLoader,@NonNull FragmentFactory factory) {if (mInstance == null) {if (mArguments != null) {mArguments.setClassLoader(classLoader);}mInstance = factory.instantiate(classLoader, mClassName);mInstance.setArguments(mArguments);if (mSavedFragmentState != null) {mSavedFragmentState.setClassLoader(classLoader);mInstance.mSavedFragmentState = mSavedFragmentState;} else {// When restoring a Fragment, always ensure we have a// non-null Bundle so that developers have a signal for// when the Fragment is being restoredmInstance.mSavedFragmentState = new Bundle();}// ...// 到这里应该挺明白了// Fragment没有默认构造就会报错,构造传参最好是走Argument}return mInstance;}
FragmentFactory
/*** Create a new instance of a Fragment with the given class name. This uses* {@link #loadFragmentClass(ClassLoader, String)} and the empty* constructor of the resulting Class by default.** @param classLoader The default classloader to use for instantiation* @param className The class name of the fragment to instantiate.* @return Returns a new fragment instance.* @throws Fragment.InstantiationException If there is a failure in instantiating* the given fragment class. This is a runtime exception; it is not* normally expected to happen.*/@NonNullpublic Fragment instantiate(@NonNull ClassLoader classLoader, @NonNull String className) {try {Class<? extends Fragment> cls = loadFragmentClass(classLoader, className);return cls.getConstructor().newInstance();}// ...}