@RitcheeQinG
2020-09-07T02:12:33.000000Z
字数 2664
阅读 396
Android
FragmentActivity
@Override
protected 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 restored
mInstance.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.
*/
@NonNull
public Fragment instantiate(@NonNull ClassLoader classLoader, @NonNull String className) {
try {
Class<? extends Fragment> cls = loadFragmentClass(classLoader, className);
return cls.getConstructor().newInstance();
}
// ...
}