1.ViewModel优点
ViewModel类旨在以注重生命周期的方式存储和管理界面相关数据。- ViewModel 类让数据可在发生屏幕旋转等配置更改后继续留存。只有当Activity真正销毁才会执行getViewModelStore().clear(),清除所有的ViewModel。
- onSaveInstanceState()只适合序列化和反序列化的少量数据。
- viewModelScope为每个ViewModel定义协程作用域,当ViewModel销毁时,协程也跟着销毁。
2.ViewModelProvider(this)创建viewmodel
val vm = ViewModelProvider(this)[ViewModelTest::class.java]
val vm by viewModels<VmTestModel>()
简述 by 属性委托 给 Lazy getValue
viewModels: ComponentActivity扩展方法,返回Lazy, Lazy.getValue()扩展方法,返回value ViewModelLazy:Lazy 重写value方法。
public ViewModelProvider(@NonNull ViewModelStoreOwner owner) {
//从当前owner中获取viewmodelStore
this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory
? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory()
: NewInstanceFactory.getInstance());
}
我们都知道ViewModel构造函数传递参数,必须使用Factory创建ViewModel
新版本依赖已经给viewmodel的Factory创建做了解耦,可以改用viewModelFactory{}无状态化构造ViewModel。感兴趣的可自行参阅
"androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
ViewModelProvider(this)默认执行的Factory 为 AndroidViewModelFactory
SavedStateViewModelFactory.kt
@SuppressLint("LambdaLast")
public SavedStateViewModelFactory(@Nullable Application application,
@NonNull SavedStateRegistryOwner owner,
@Nullable Bundle defaultArgs) {
mSavedStateRegistry = owner.getSavedStateRegistry();
mLifecycle = owner.getLifecycle();
mDefaultArgs = defaultArgs;
mApplication = application;
mFactory = application != null
? ViewModelProvider.AndroidViewModelFactory.getInstance(application)
: ViewModelProvider.NewInstanceFactory.getInstance();
}
get(VM:class.java) 创建和保存
@NonNull
@MainThread
public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
//首先从缓存中获取
ViewModel viewModel = mViewModelStore.get(key);
if (modelClass.isInstance(viewModel)) {
if (mFactory instanceof OnRequeryFactory) {
((OnRequeryFactory) mFactory).onRequery(viewModel);
}
//
return (T) viewModel;
} else {
//noinspection StatementWithEmptyBody
if (viewModel != null) {
// TODO: log a warning.
}
}
if (mFactory instanceof KeyedFactory) {
viewModel = ((KeyedFactory) mFactory).create(key, modelClass);
} else {
//从工厂中创建
viewModel = mFactory.create(modelClass);
}
//保存在 ViewModelStore的HashMap里
mViewModelStore.put(key, viewModel);
return (T) viewModel;
}
AndroidViewModelFactory.create()
反射创建ViewModel对象
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
if (AndroidViewModel.class.isAssignableFrom(modelClass)) {
//noinspection TryWithIdenticalCatches
try {
//反射创建ViewModel对象
return modelClass.getConstructor(Application.class).newInstance(mApplication);
} catch (NoSuchMethodException e) {
}
return super.create(modelClass);
}
3.ViewModel 保存和销毁
VieModelProvider(this)[ViewModelTest::class.java]。
ViewModelStore.kt
mMap储存当前Activity所有的Viewmodel
public class ViewModelStore {
private final HashMap<String, ViewModel> mMap = new HashMap<>();
//保存viewmodel
final void put(String key, ViewModel viewModel) {
ViewModel oldViewModel = mMap.put(key, viewModel);
if (oldViewModel != null) {
oldViewModel.onCleared();
}
}
//获取ViewModel实例
final ViewModel get(String key) {
return mMap.get(key);
}
Set<String> keys() {
return new HashSet<>(mMap.keySet());
}
//通知每个Viewmodel不可用,并清楚所有的ViewModel
public final void clear() {
for (ViewModel vm : mMap.values()) {
vm.clear();
}
mMap.clear();
}
}
getViewModelStore()
//实现ViewModelStoreOwner 重写getViewModelStore()
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
ContextAware,
LifecycleOwner,
ViewModelStoreOwner,
HasDefaultViewModelProviderFactory,
SavedStateRegistryOwner,
OnBackPressedDispatcherOwner,
ActivityResultRegistryOwner,
ActivityResultCaller {
//获取viemodelStore
@NonNull
@Override
public ViewModelStore getViewModelStore() {
...
ensureViewModelStore();
return mViewModelStore;
}
}
//viewModelStore 初始化
void ensureViewModelStore() {
if (mViewModelStore == null) {
//先从最后一次保存的配置里获取
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
//尝试恢复
mViewModelStore = nc.viewModelStore;
}
//没有获取到直接创建新的
if (mViewModelStore == null) {
mViewModelStore = new ViewModelStore();
}
}
}
@SuppressWarnings("WeakerAccess")
public interface ViewModelStoreOwner {
@NonNull
ViewModelStore getViewModelStore();
}
onRetainNonConfigurationInstance()
当手机配置发生改变(旋转屏幕)Activity 会销毁,重走onCreate, 但是在onDestory之前执行保存操作
public final Object onRetainNonConfigurationInstance() {
// Maintain backward compatibility.
Object custom = onRetainCustomNonConfigurationInstance();
//获取当前的viewmodelStore
ViewModelStore viewModelStore = mViewModelStore;
if (viewModelStore == null) {
//如果为空,配置中读取
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
viewModelStore = nc.viewModelStore;
}
}
//没有获取到,直接返回
if (viewModelStore == null && custom == null) {
return null;
}
//创建 instances实例保存 VewModelStore
NonConfigurationInstances nci = new NonConfigurationInstances();
nci.custom = custom;
nci.viewModelStore = viewModelStore;
return nci;
}
NonConfigurationInstances(viewmodelStore) 的保存
static final class NonConfigurationInstances {
Object custom;
ViewModelStore viewModelStore;
}
viewmodelStore 状态恢复
public ComponentActivity() {
Lifecycle lifecycle = getLifecycle();
//清除viewmodelStore里的viewmodel
getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_DESTROY) {
// Clear out the available context
mContextAwareHelper.clearAvailableContext();
// 清除所有viewmodel
if (!isChangingConfigurations()) {
getViewModelStore().clear();
}
}
}
});
//当执行onCreate 时候恢复数据
getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
//从配置从恢复
ensureViewModelStore();
//移除Observer
getLifecycle().removeObserver(this);
}
});
}
4.配置改变ViewModel保存在什么地方的?
onRetainNonConfigurationInstace,getLastNonConfigurationInstance()怎么保存和恢复的呢
1.handleDestroyActivity()
当activity销毁时,ActivityThread 执行 handleDestroyActivity
@Override
public void handleDestroyActivity(ActivityClientRecord r, boolean finishing, int configChanges,
boolean getNonConfigInstance, String reason) {
performDestroyActivity(r, finishing, configChanges, getNonConfigInstance, reason);
}
void performDestroyActivity(ActivityClientRecord r, boolean finishing,
int configChanges, boolean getNonConfigInstance, String reason) {
...
//如果是配置发生改变
if (getNonConfigInstance) {
//把 retainNonConfigurationInstances的值复制给ActivityClientRecord的lastNonConfigurationInstances
r.lastNonConfigurationInstances =
r.activity.retainNonConfigurationInstances();
}
...
ActivityClientRecord 是保存在ActivityThread.java下的mActivities中
final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
activity.retainNonConfigurationInstances()
retainNonConfigurationInstances()
NonConfigurationInstances retainNonConfigurationInstances() {
//调用onRetainNonConfiguration()
//获取当前保存的viewmodelStore的NonConfigurationInstance实列
Object activity = onRetainNonConfigurationInstance();
=...
//activity 保存在 NonConfigurationInstances
NonConfigurationInstances nci = new NonConfigurationInstances();
nci.activity = activity;
...
return nci;
}
NonConfigurationInstances
static final class NonConfigurationInstances {
Object activity;
HashMap<String, Object> children;
FragmentManagerNonConfig fragments;
ArrayMap<String, LoaderManager> loaders;
VoiceInteractor voiceInteractor;
}
执行完onDestory 对象已经保存在 r.lastNonConfigurationInstances
2.handleLaunchActivity
attach()
final Activity a = performLaunchActivity(r, customIntent);
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
....
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken, r.shareableActivityToken);
....
}
将保存的对象赋值给Activity的 成员变量 mLastNonConfigurationInstances
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
final void attach(Context context
...
NonConfigurationInstances lastNonConfigurationInstances,
...
) {
...
///赋值给mLastNonConfigurationInstances
mLastNonConfigurationInstances = lastNonConfigurationInstances;
getLastNonConfigurationInstance()
getLastNonConfigurationInstance 获取的就是mLastNonConfigurationInstance的值
@Nullable
public Object getLastNonConfigurationInstance() {
return mLastNonConfigurationInstances != null
? mLastNonConfigurationInstances.activity : null;
}
5.总结
当Activity 销毁时,viewModelStore 通过 onRetainNonConfigurationInstance()
装箱到NonConfigurationInstances对象里,并储存到ActivityClientRecord(简称r)实列里,
而r又存储在ActivityThread的成员变量mActivities里,当Activity重建时,
从r对象中获取NonConfigurationInstances并存储到Activity的成员变量mLastNonConfigurationInstances,
当activity执行oncreate时,从mLastNonConfigurationInstances.viewmodelStore恢复viewmodelStore,
所以从viewmodelStore中获取的Viewmodel是同一对象。
5. 屏幕旋转事件
1.ActivityManagerService.updateConfiguration
@Override
public boolean updateConfiguration(Configuration values) {
return mActivityTaskManager.updateConfiguration(values);
}
2.ActivityTaskManagerService
@Override
public boolean updateConfiguration(Configuration values) {
...
updateConfigurationLocked(values, null, false, false /* persistent */,
UserHandle.USER_NULL, false /* deferResume */,
mTmpUpdateConfigurationResult);
...
}
boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
boolean initLocale, boolean persistent, int userId, boolean deferResume,
ActivityTaskManagerService.UpdateConfigurationResult result) {
...
if (!deferResume) {
kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
}
...
return kept;
}
ensureConfigAndVisibilityAfterUpdate() -> relaunchActivityLocked(preserveWindow);
3.relaunchActivityLocked
try {
final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults,
pendingNewIntents, configChangeFlags,
new MergedConfiguration(getProcessGlobalConfiguration(),
getMergedOverrideConfiguration()),
preserveWindow);
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(isTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
final ClientTransaction transaction = ClientTransaction.obtain(app.getThread(), appToken);
transaction.addCallback(callbackItem);
transaction.setLifecycleStateRequest(lifecycleItem);
mAtmService.getLifecycleManager().scheduleTransaction(transaction);
执行ActivityRelaunchItem
@Override
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
if (mActivityClientRecord == null) {
if (DEBUG_ORDER) Slog.d(TAG, "Activity relaunch cancelled");
return;
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
client.handleRelaunchActivity(mActivityClientRecord, pendingActions);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
4.ActivityThread.handleRelaunchActivity()
@Override
public void handleRelaunchActivity(ActivityClientRecord tmp,
PendingTransactionActions pendingActions) {
handleRelaunchActivityInner(r, configChanges, tmp.pendingResults, tmp.pendingIntents,
pendingActions, tmp.startsNotResumed, tmp.overrideConfig, "handleRelaunchActivity");
}
handleRelaunchActivityInner
private void handleRelaunchActivityInner(ActivityClientRecord r, int configChanges,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingIntents,
PendingTransactionActions pendingActions, boolean startsNotResumed,
Configuration overrideConfig, String reason) {
// Preserve last used intent, it may be set from Activity#setIntent().
final Intent customIntent = r.activity.mIntent;
// Need to ensure state is saved.
if (!r.paused) {
//执行onPause
performPauseActivity(r, false, reason, null /* pendingActions */);
}
if (!r.stopped) {
// onStop
callActivityOnStop(r, true /* saveState */, reason);
}
//onDestory 也是在这里保存调用onRetainNonConfigurationInstance 来保存状态的
handleDestroyActivity(r, false, configChanges, true, reason);
r.activity = null;
r.window = null;
r.hideForNow = false;
r.nextIdle = null;
// Merge any pending results and pending intents; don't just replace them
if (pendingResults != null) {
if (r.pendingResults == null) {
r.pendingResults = pendingResults;
} else {
r.pendingResults.addAll(pendingResults);
}
}
if (pendingIntents != null) {
if (r.pendingIntents == null) {
r.pendingIntents = pendingIntents;
} else {
r.pendingIntents.addAll(pendingIntents);
}
}
r.startsNotResumed = startsNotResumed;
r.overrideConfig = overrideConfig;
//重新执行 , getLastNonConfigurationInstance 的 attach 完成赋值
handleLaunchActivity(r, pendingActions, customIntent);
}