/** * Returns the `ViewModel` mapped to the given `key` or null if none exists. */ /** * @hide */ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) operatorfunget(key: String): ViewModel? { return map[key] }
/** * Clears internal storage and notifies `ViewModel`s that they are no longer used. */ funclear() { for (vm in map.values) { vm.clear() } map.clear() } }
@MainThread publicopenoperatorfun<T : ViewModel>get(modelClass: Class<T>): T { val canonicalName = modelClass.canonicalName ?: throw IllegalArgumentException("Local and anonymous classes can not be ViewModels") returnget("$DEFAULT_KEY:$canonicalName", modelClass) }
publicopenoperatorfun<T : ViewModel>get(key: String, modelClass: Class<T>): T { val viewModel = store[key] // 1️⃣ 从store中取viewModel if (modelClass.isInstance(viewModel)) { // 2️⃣ 判断合法性 (factory as? OnRequeryFactory)?.onRequery(viewModel!!) return viewModel as T } else { @Suppress("ControlFlowWithEmptyBody") if (viewModel != null) { // TODO: log a warning. } } val extras = MutableCreationExtras(defaultCreationExtras) extras[VIEW_MODEL_KEY] = key // AGP has some desugaring issues associated with compileOnly dependencies so we need to // fall back to the other create method to keep from crashing. returntry { factory.create(modelClass, extras) // 3️⃣ 通过factory创建ViewModel } catch (e: AbstractMethodError) { // 3️⃣ 通过factory创建ViewModel factory.create(modelClass) }.also { store.put(key, it) } // 4️⃣ 存入store }
funaddCloseable(key: String, closeable: AutoCloseable) { // Although no logic should be done after user calls onCleared(), we will // ensure that if it has already been called, the closeable attempting to // be added will be closed immediately to ensure there will be no leaks. if (isCleared) { closeWithRuntimeException(closeable) return }
val oldCloseable = synchronized(lock) { keyToCloseables.put(key, closeable) } closeWithRuntimeException(oldCloseable) }
/** @see [ViewModel.addCloseable] */ funaddCloseable(closeable: AutoCloseable) { // Although no logic should be done after user calls onCleared(), we will // ensure that if it has already been called, the closeable attempting to // be added will be closed immediately to ensure there will be no leaks. if (isCleared) { closeWithRuntimeException(closeable) return }
@MainThread funclear() { if (isCleared) return// 1️⃣
isCleared = true// 2️⃣ synchronized(lock) { for (closeable in keyToCloseables.values) { closeWithRuntimeException(closeable) } for (closeable in closeables) { closeWithRuntimeException(closeable) } // Clear only resources without keys to prevent accidental recreation of resources. // For example, `viewModelScope` would be recreated leading to unexpected behaviour. closeables.clear() } }
overridefun<T : ViewModel>create(modelClass: Class<T>, extras: CreationExtras): T { // 1️⃣ val key = extras[ViewModelProvider.NewInstanceFactory.VIEW_MODEL_KEY] ?: throw IllegalStateException( "VIEW_MODEL_KEY must always be provided by ViewModelProvider" )
returnif (extras[SAVED_STATE_REGISTRY_OWNER_KEY] != null && extras[VIEW_MODEL_STORE_OWNER_KEY] != null) { val application = extras[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] val isAndroidViewModel = AndroidViewModel::class.java.isAssignableFrom(modelClass) valconstructor: Constructor<T>? = if (isAndroidViewModel && application != null) { findMatchingConstructor(modelClass, ANDROID_VIEWMODEL_SIGNATURE) } else { findMatchingConstructor(modelClass, VIEWMODEL_SIGNATURE) } // doesn't need SavedStateHandle if (constructor == null) { return factory.create(modelClass, extras) } val viewModel = if (isAndroidViewModel && application != null) { newInstance(modelClass, constructor, application, extras.createSavedStateHandle()) } else { newInstance(modelClass, constructor, extras.createSavedStateHandle()) } viewModel } else { val viewModel = if (lifecycle != null) { create(key, modelClass) } else { throw IllegalStateException("SAVED_STATE_REGISTRY_OWNER_KEY and" + "VIEW_MODEL_STORE_OWNER_KEY must be provided in the creation extras to" + "successfully create a ViewModel.") } viewModel } }
/** * Creates a new instance of the given `Class`. * * @param key a key associated with the requested ViewModel * @param modelClass a `Class` whose instance is requested * @return a newly created ViewModel * * @throws UnsupportedOperationException if the there is no lifecycle */ fun<T : ViewModel>create(key: String, modelClass: Class<T>): T { // 2️⃣ // empty constructor was called. val lifecycle = lifecycle ?: throw UnsupportedOperationException( "SavedStateViewModelFactory constructed with empty constructor supports only " + "calls to create(modelClass: Class<T>, extras: CreationExtras)." ) val isAndroidViewModel = AndroidViewModel::class.java.isAssignableFrom(modelClass) valconstructor: Constructor<T>? = if (isAndroidViewModel && application != null) { findMatchingConstructor(modelClass, ANDROID_VIEWMODEL_SIGNATURE) } else { findMatchingConstructor(modelClass, VIEWMODEL_SIGNATURE) } // doesn't need SavedStateHandle constructor ?: // If you are using a stateful constructor and no application is available, we // use an instance factory instead. returnif (application != null) factory.create(modelClass) else instance.create(modelClass) val controller = LegacySavedStateHandleController.create( savedStateRegistry!!, lifecycle, key, defaultArgs ) val viewModel: T = if (isAndroidViewModel && application != null) { newInstance(modelClass, constructor, application!!, controller.handle) } else { newInstance(modelClass, constructor, controller.handle) } viewModel.setTagIfAbsent( AbstractSavedStateViewModelFactory.TAG_SAVED_STATE_HANDLE_CONTROLLER, controller ) return viewModel }
internalfun<T : ViewModel?>newInstance( modelClass: Class<T>, constructor: Constructor<T>, vararg params: Any ): T { returntry { constructor.newInstance(*params) } catch (e: IllegalAccessException) { throw RuntimeException("Failed to access $modelClass", e) } catch (e: InstantiationException) { throw RuntimeException("A $modelClass cannot be instantiated.", e) } catch (e: InvocationTargetException) { throw RuntimeException( "An exception happened in constructor of $modelClass", e.cause ) } }
viewModelStore何时被clear
在ComponentActivty的初始化时,会看到下面这段代码
1 2 3 4 5 6 7 8 9 10 11
lifecycle.addObserver(LifecycleEventObserver { _, event -> if (event == Lifecycle.Event.ON_DESTROY) { // Clear out the available context contextAwareHelper.clearAvailableContext() // And clear the ViewModelStore if (!isChangingConfigurations) { viewModelStore.clear() } reportFullyDrawnExecutor.activityDestroyed() } })
/** * [CoroutineScope] that provides a method to [close] it, causing the rejection of any new tasks and * cleanup of all underlying resources associated with the scope. */ internalclassCloseableCoroutineScope( overrideval coroutineContext: CoroutineContext, ) : AutoCloseable, CoroutineScope {
overrideval defaultViewModelCreationExtras: CreationExtras /** * {@inheritDoc} * * The extras of [getIntent] when this is first called will be used as * the defaults to any [androidx.lifecycle.SavedStateHandle] passed to a view model * created using this extra. */ get() { val extras = MutableCreationExtras() if (application != null) { extras[APPLICATION_KEY] = application } extras[SAVED_STATE_REGISTRY_OWNER_KEY] = this extras[VIEW_MODEL_STORE_OWNER_KEY] = this val intentExtras = intent?.extras if (intentExtras != null) { extras[DEFAULT_ARGS_KEY] = intentExtras } return extras }
val parentFragmentViewModel:XXXViewModel by viewModels(ownerProducer = { requireParentFragment() })
navigation图的viewModel
1 2
val naviViewModel : MainViewModel by navGraphViewModels(R.id.xxx) val naviViewModel1 : MainViewModel by viewModels(ownerProducer = { findNavController().getBackStackEntry(R.id.xxx) })
interfaceHasDefaultViewModelProviderFactory { /** * Returns the default [ViewModelProvider.Factory] that should be * used when no custom `Factory` is provided to the * [ViewModelProvider] constructors. */ val defaultViewModelProviderFactory: ViewModelProvider.Factory
/** * Returns the default [CreationExtras] that should be passed into * [ViewModelProvider.Factory.create] when no overriding * [CreationExtras] were passed to the [ViewModelProvider] constructors. */ val defaultViewModelCreationExtras: CreationExtras get() = CreationExtras.Empty }