/**
* An interface for an owner of this [SavedStateRegistry] to perform state saving, it will call
* all registered providers and merge with unconsumed state.
*
* @param outBundle SavedState in which to place a saved state
*/@MainThreadinternalfunperformSave(outBundle:SavedState){valinState=savedState{restoredState?.let{putAll(it)}synchronized(lock){for((key,provider)inkeyToProviders){putSavedState(key,provider.saveState())}}}if(inState.read{!isEmpty()}){outBundle.write{putSavedState(SAVED_COMPONENTS_KEY,inState)}}}
#FragmentStateManager.java@NonNullBundlesaveState(){BundlestateBundle=newBundle();if(mFragment.mState==Fragment.INITIALIZING){// We never even got to ATTACHED, but we could still have some state// set by setInitialSavedState so we'll add that to our initial Bundleif(mFragment.mSavedFragmentState!=null){stateBundle.putAll(mFragment.mSavedFragmentState);}}// Save the library state associated with the FragmentFragmentStatefs=newFragmentState(mFragment);stateBundle.putParcelable(FRAGMENT_STATE_KEY,fs);// Save the user state associated with the Fragmentif(mFragment.mState>Fragment.INITIALIZING){BundlesavedInstanceState=newBundle();mFragment.performSaveInstanceState(savedInstanceState);if(!savedInstanceState.isEmpty()){stateBundle.putBundle(SAVED_INSTANCE_STATE_KEY,savedInstanceState);}mDispatcher.dispatchOnFragmentSaveInstanceState(mFragment,savedInstanceState,false);BundlesavedStateRegistryState=newBundle();mFragment.mSavedStateRegistryController.performSave(savedStateRegistryState);if(!savedStateRegistryState.isEmpty()){stateBundle.putBundle(REGISTRY_STATE_KEY,savedStateRegistryState);}BundlechildFragmentManagerState=mFragment.mChildFragmentManager.saveAllStateInternal();if(!childFragmentManagerState.isEmpty()){stateBundle.putBundle(CHILD_FRAGMENT_MANAGER_KEY,childFragmentManagerState);}if(mFragment.mView!=null){saveViewState();}if(mFragment.mSavedViewState!=null){stateBundle.putSparseParcelableArray(VIEW_STATE_KEY,mFragment.mSavedViewState);}if(mFragment.mSavedViewRegistryState!=null){stateBundle.putBundle(VIEW_REGISTRY_STATE_KEY,mFragment.mSavedViewRegistryState);}}if(mFragment.mArguments!=null){stateBundle.putBundle(ARGUMENTS_KEY,mFragment.mArguments);}returnstateBundle;}
// FragmentStateManager.java/**
* Recreate a FragmentStateManager from a FragmentState instance, instantiating
* a new Fragment from the {@link FragmentFactory}.
*
* @param dispatcher Dispatcher for any lifecycle callbacks triggered by this class
* @param fragmentStore FragmentStore handling all Fragments
* @param classLoader ClassLoader used to instantiate the Fragment
* @param fragmentFactory FragmentFactory used to instantiate the Fragment
* @param state Bundle used to restore the state correctly
*/@SuppressWarnings("deprecation")FragmentStateManager(@NonNullFragmentLifecycleCallbacksDispatcherdispatcher,@NonNullFragmentStorefragmentStore,@NonNullClassLoaderclassLoader,@NonNullFragmentFactoryfragmentFactory,@NonNullBundlestate){mDispatcher=dispatcher;mFragmentStore=fragmentStore;// Instantiate the fragment's library states in FragmentStateFragmentStatefs=state.getParcelable(FRAGMENT_STATE_KEY);mFragment=fs.instantiate(fragmentFactory,classLoader);mFragment.mSavedFragmentState=state;// Instantiate the fragment's argumentsBundlearguments=state.getBundle(ARGUMENTS_KEY);if(arguments!=null){arguments.setClassLoader(classLoader);}mFragment.setArguments(arguments);if(FragmentManager.isLoggingEnabled(Log.VERBOSE)){Log.v(TAG,"Instantiated fragment "+mFragment);}}// FragmentState.java/**
* Instantiates the Fragment from this state.
*/@NonNull@SuppressWarnings("deprecation")Fragmentinstantiate(@NonNullFragmentFactoryfragmentFactory,@NonNullClassLoaderclassLoader){Fragmentfragment=fragmentFactory.instantiate(classLoader,mClassName);fragment.mWho=mWho;fragment.mFromLayout=mFromLayout;fragment.mRestored=true;fragment.mFragmentId=mFragmentId;fragment.mContainerId=mContainerId;fragment.mTag=mTag;fragment.mRetainInstance=mRetainInstance;fragment.mRemoving=mRemoving;fragment.mDetached=mDetached;fragment.mHidden=mHidden;fragment.mMaxState=Lifecycle.State.values()[mMaxLifecycleState];fragment.mTargetWho=mTargetWho;fragment.mTargetRequestCode=mTargetRequestCode;fragment.mUserVisibleHint=mUserVisibleHint;returnfragment;}// FragmentFactory.java/**
* 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.
*/@NonNullpublicFragmentinstantiate(@NonNullClassLoaderclassLoader,@NonNullStringclassName){try{Class<?extendsFragment>cls=loadFragmentClass(classLoader,className);returncls.getConstructor().newInstance();}catch(java.lang.InstantiationExceptione){thrownewFragment.InstantiationException("Unable to instantiate fragment "+className+": make sure class name exists, is public, and has an"+" empty constructor that is public",e);}catch(IllegalAccessExceptione){thrownewFragment.InstantiationException("Unable to instantiate fragment "+className+": make sure class name exists, is public, and has an"+" empty constructor that is public",e);}catch(NoSuchMethodExceptione){thrownewFragment.InstantiationException("Unable to instantiate fragment "+className+": could not find Fragment constructor",e);}catch(InvocationTargetExceptione){thrownewFragment.InstantiationException("Unable to instantiate fragment "+className+": calling Fragment constructor caused an exception",e);}}