本文涉及的源码版本以下:java
ViewModel用于存储和管理UI相关的数据,ViewModel有本身生命周期,会根据fragment,activity的生命周期销毁。当配置发生改变时, ViewModel存储的数据仍是存在的,不会被销毁。(例如旋转屏幕,旋转屏幕一般会致使activity重建)android
ViewModel:抽象类,onCleared方法用于释放资源bash
AndroidViewModel: 继承了ViewModel, 没什么区别, 构造能够传入一个application网络
ViewModelStore: ViewModel存储器, 内部Map存储多线程
ViewModelStoreOwner: 一个接口, ViewModelStore拥有者。 Fragment和FragmentActivity实现了接口app
Factory: 一个工厂接口,用于建立ViewModel。是ViewModelProvider的内部接口异步
NewInstanceFactory: 继承Factory, 经过反射class.newInstance()产生一个ViewModel。因此使用这个Factory,ViewModel须要有空参构造器。ide
AndroidViewModelFactory: 继承Factory, 也是经过反射产生一个AndroidViewModel, 并且这个AndroidViewModel构造器必须只有一个application参数, 如何反射建立失败会调用NewInstanceFactory去建立。工具
ViewModelProvider: 是一个帮助类,构造器能够传入ViewModelStore和Factory, 会根据Factory产生一个ViewModel, 并存储到ViewModelStore里。post
ViewModel的生命周期是跟fragment, activity生命周期关联的。只有fragment, activity销毁时才会调用ViewModel.onCleared() (配置改为致使销毁,不会调用onCleared)
ViewModel存储在ViewModelStore, ViewModel的onCleared方法在ViewModelStore的clear方法时被调用, ViewModelStore源码以下:
private final HashMap<String, ViewModel> mMap = new HashMap<>();
/** * Clears internal storage and notifies ViewModels that they are no longer used. */
public final void clear() {
for (ViewModel vm : mMap.values()) {
vm.onCleared();
}
mMap.clear();
}
复制代码
下面看看Fragment, 和FragmentActivity的实现,先看Fragment的实现:
public ViewModelStore getViewModelStore() {
if (getContext() == null) {
throw new IllegalStateException("Can't access ViewModels from detached fragment");
}
// new一个ViewModelStore, 一个Fragment只有一个ViewModelStore
if (mViewModelStore == null) {
mViewModelStore = new ViewModelStore();
}
return mViewModelStore;
}
public void onDestroy() {
mCalled = true;
// Use mStateSaved instead of isStateSaved() since we're past onStop()
if (mViewModelStore != null && !mHost.mFragmentManager.mStateSaved) {
mViewModelStore.clear(); // mStateSaved用于判读是否因为配置改变致使Fragment重建
}
}
复制代码
再看FragmentActivity的实现
public ViewModelStore getViewModelStore() {
if (getApplication() == null) {
throw new IllegalStateException("Your activity is not yet attached to the "
+ "Application instance. You can't request ViewModel before onCreate call.");
}
if (mViewModelStore == null) {
mViewModelStore = new ViewModelStore();
}
return mViewModelStore;
}
protected void onDestroy() {
super.onDestroy();
....
if (mViewModelStore != null && !mRetaining) {
// mRetaining用于判读是否因为配置改变致使Fragment重建
mViewModelStore.clear();
}
}
复制代码
ViewModel存储的数据不会在配置改变时而销毁, ViewModel是怎样保存的呢,看前面的分析在Fragment, FragmentActivity都有一个mViewModelStore的成员变量,只要保存好这个mViewModelStore这个就能够啦。当配置改变时,在onSaveInstanceState里保存数据,而后在onRestoreInstanceState恢复数据,可是这两个方法存储数据只能放在Bundle, 只能存小量数据, 过大会抛TransactionTooLargeException异常。因此不合适,看源码发现是利用Activity的onRetainNonConfigurationInstance()和getLastNonConfigurationInstance()。
// FragmentActivity关键代码
public final Object onRetainNonConfigurationInstance() {
Object custom = onRetainCustomNonConfigurationInstance();
// 这方法继承自Activty, 且把方法定义成final,不让子类实现,可是提供onRetainCustomNonConfigurationInstance方法
FragmentManagerNonConfig fragments = mFragments.retainNestedNonConfig();
//fragments是当前activity全部fragment须要保存的数据
if (fragments == null && mViewModelStore == null && custom == null) {
return null;
}
NonConfigurationInstances nci = new NonConfigurationInstances();
nci.custom = custom;
nci.viewModelStore = mViewModelStore;
nci.fragments = fragments;
// mViewModelStore 和 fragments 就存在NonConfigurationInstances里
return nci;
}
protected void onCreate(@Nullable Bundle savedInstanceState) {
...
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
// 调用getLastNonConfigurationInstance方法获取NonConfigurationInstances恢复数据
if (nc != null) {
mViewModelStore = nc.viewModelStore;
}
if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
mFragments.restoreAllState(p, nc != null ? nc.fragments : null);
//nc.fragments经过mFragments.restoreAllState()恢复
}
...
}
复制代码
这里onRetainNonConfigurationInstance和getLastNonConfigurationInstance方法就不深刻啦,配置改变时还想保存一些自定义object数据能够重写onRetainCustomNonConfigurationInstance去实现。那Fragment的mViewModelStore呢,就是mFragments.retainNestedNonConfig() 和 mFragments.restoreAllState() 这两个方法啦。 mFragments是FragmentController实例,最后是调用到FragmentManager, 而FragmentManager真正实现是FragmentManagerImpl。下面截取部分FragmentManagerImpl的关键代码。
// 这个方法就Activity里mFragments.retainNestedNonConfig()最终调用的方法
FragmentManagerNonConfig retainNonConfig() {
setRetaining(mSavedNonConfig); // 因为篇幅的缘由, 这个方法本文不展开了
return mSavedNonConfig;
}
//来看mSavedNonConfig这个实例是在哪里建立的,回到FragmentActivity.onSaveInstanceState方法里发现调用mFragments.saveAllState()保存状态,最终来到FragmentManagerImpl的saveAllState()
Parcelable saveAllState() {
mSavedNonConfig = null;
saveNonConfig();
}
void saveNonConfig() {
ArrayList<Fragment> fragments = null;
ArrayList<FragmentManagerNonConfig> childFragments = null;
ArrayList<ViewModelStore> viewModelStores = null;
if (mActive != null) {
//mActive是SparseArray<Fragment>, 表明fragment栈, 遍历mActive,
for (int i=0; i<mActive.size(); i++) {
Fragment f = mActive.valueAt(i);
if (f != null) {
...
if (viewModelStores != null) {
// 把fragment的成员变量mViewModelStore添加到list中
viewModelStores.add(f.mViewModelStore);
}
}
}
}
if (fragments == null && childFragments == null && viewModelStores == null) {
mSavedNonConfig = null;
} else {
//viewModelStores存储到FragmentManagerNonConfig里
mSavedNonConfig = new FragmentManagerNonConfig(fragments, childFragments,
viewModelStores);
}
}
//mFragments.restoreAllState() 最终调用FragmentManagerImpl的restoreAllState()
void restoreAllState(Parcelable state, FragmentManagerNonConfig nonConfig) {
if (state == null) return;
FragmentManagerState fms = (FragmentManagerState)state;
//fms是保存状态时存储在Parcelable的,如今拿出来恢复状态
if (fms.mActive == null) return;
//这里有不少种状况,这里大概分析常见的恢复过程
...
mActive = new SparseArray<>(fms.mActive.length);
//遍历FragmentState
for (int i=0; i<fms.mActive.length; i++) {
FragmentState fs = fms.mActive[i];
if (fs != null) {
...
ViewModelStore viewModelStore = null;
if (viewModelStores != null && i < viewModelStores.size()) {
viewModelStore = viewModelStores.get(i);
}
Fragment f = fs.instantiate(mHost, mContainer, mParent, childNonConfig,
viewModelStore);
// 传入viewModelStore, 调用instantiate方法从新生成Fragment
if (DEBUG) Log.v(TAG, "restoreAllState: active #" + i + ": " + f);
mActive.put(f.mIndex, f);
}
}
}
复制代码
LiveData是一个可观察数据的持有者, 可是不像普通的可观察数据, LiveData是绑定了生命周期,例如activitie, fragment的生命周期。有点抽象, 仍是先了解一下关键的类。
//Observer是一个接口,观察者。当数据改变时就回调onChanged
public interface Observer<T> {
void onChanged(@Nullable T t);
}
//LiveData类是个抽象类,这里先看看有什么暴露出去的方法
public abstract class LiveData<T> {
//添加观察者观察, 传入LifecycleOwner,用于来绑定生命周期
public void observe(LifecycleOwner owner, Observer<T> observer) //添加观察者观察, 可是是没有LifecycleOwner public void observeForever(Observer<T> observer) //移除观察者 public void removeObserver(Observer<T> observer) //移除某个LifecycleOwner里全部的观察者 public void removeObservers(final LifecycleOwner owner) //是否有观察者 public boolean hasObservers() //是否有活的观察者 public boolean hasActiveObservers() } //MutableLiveData继承LiveData, 多开放2个方法。 public class MutableLiveData<T> extends LiveData<T> {
public void postValue(T value) //post一个数据 public void setValue(T value) //设置一个数据 //postValue和setValue的区别是:post能够在子线程用,而setValue只能在UI线程调用 } 复制代码
介绍完了主要的类,下面举个例子:
// 这段代码一般在Activity或者Fragment中, 用liveData去添加一个观察者
// AppCompatActivity或者Fragment已经LifecycleOwner,一般传this便可
// 当User数据有变化时,onChanged方法会被调用, 用于更新UI
liveData.observe(this, new Observer<User>() {
@Override
public void onChanged(@Nullable User user) {
//更新UI
}
});
//下面这段代码一般在ViewModel中,这里liveData和上面代码的liveData是同一个
//能够经过postValue或者setValue去改为user数据, 有数据改变时, onChanged方法会被回调
//假如一个场景, 在ViewModel中,经过网络请求去拿user数据,而后postValue就会去通知UI层onChanged去更新UI
//liveData大概就是这个流程
liveData = new MutableLiveData<User>()
liveData.postValue(user)// 或者setValue(user)
复制代码
下面仍是看看LiveData源码去了解一下原理
这里以observe(LifecycleOwner owner, Observer observer) 和 postValue之间数据的通信为例分析。对LifecycleOwner不熟悉的能够看个人上一篇文章:LifecycleOwner, 下面看LiveData.observe源码:
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
//判断当前生命周期是DESTROYED, 立马return, 都销毁了,添加观察者没意义
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
//LifecycleBoundObserver继承ObserverWrapper, LifecycleBoundObserver实现LifecycleOwner
//mObservers这是一个Map, key是observer, value是ObserverWrapper
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
//添加生命周期的观察者
owner.getLifecycle().addObserver(wrapper);
}
复制代码
接着看LifecycleBoundObserver和ObserverWrapper片断:
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull final LifecycleOwner mOwner;
@Override
boolean shouldBeActive() {
//至少是STARTED状态
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
//GenericLifecycleObserver继承自LifecycleObserver, 当生命周期改变时onStateChanged会被回调
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
//生命周期处于DESTROYED时, 移除观察者,mObserver是livedata.observe时传进来
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
//shouldBeActive()方法实如今当前类, 调用isAtLeast(STARTED), 至少是STARTED状态才是true
//就是生命周期在STARTED和RESUME状态时, 才是true
//接着调用了父类的activeStateChanged
activeStateChanged(shouldBeActive());
}
}
private abstract class ObserverWrapper {
void activeStateChanged(boolean newActive) {
// mActive状态相同当即返回
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
//就是生命周期在STARTED和RESUME时, mActive为true, 其余为false
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += mActive ? 1 : -1;
//当mActive=true时, mActiveCount会加1, 当mActive=false时, mActiveCount会减1。
//这里为何要加1和减1呢,结合Activity生命周期去考虑,当Activity.onCreate -> Activity.onStart -> Activity.onResume, State由CREATED->STARTED->RESUMED,这个过程当到STARTED时mActive为true,mActiveCount加1后为1, 接着RESUMED, mActive仍是true, 这方法第一句(newActive == mActive)条件成立直接return, mActiveCount此时仍是1。
//当Activity.onResume->Activity.onPause->Activity.onStop,State由RESUMED->STARTED->CREATED, Activity.onStop后State为CREATED, isAtLeast(STARTED)就为false, 此时mActive=false, mActiveCount减1,mActiveCount为0啦。
//当Activity.onStop->Activity.onStart->Activity.onResume, State由CREATED->STARTED->RESUMED, mActive为true,mActiveCount加1后为1, mActiveCount此时为1。
if (wasInactive && mActive) {
//根据上面一大段分析后,onActive会在Activity首次显示UI调用,从后台返回或者从另外一个Activity回退后又调用一次。(打开透明Activity不走onStop,这种状况除外)
onActive();
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
// Activity.onStop后调用
onInactive();
}
if (mActive) {
//分发数据, 跟踪dispatchingValue方法,会到LiveData.considerNotify方法
dispatchingValue(this);
}
}
}
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
//mActive能够知道是否处于onStop状态, 是Stop状态就不要分发数据
return;
}
if (!observer.shouldBeActive()) {
//shouldBeActive()再次检查是否observer活着
//ObserverWrapper的实现类不止LifecycleBoundObserver, 这里暂时没看懂为何再次检查
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
//mVersion会在调用postValue()或者setValue()处+1
return;
}
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
调用onChanged分发改变的数据
}
复制代码
接着看postValue方法是是若是把值传到onChanged里:
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
// 一开始看到这里有点疑问,1. 为何加锁, 1. 为何要一个NOT_SET变量(NOT_SET是一个Obj对象)
// 先带着疑问往下看
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) { // 先往下看,和加锁问题一块儿解释
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
// mPostValueRunnable运行在主线程
}
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) { //加锁, 和postValue里的锁是同样的
newValue = mPendingData;
mPendingData = NOT_SET;
}
setValue((T) newValue);
}
};
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++; // 版本号加1,保证mVersion>mLastVersion
mData = value; // 赋值给mData, 数据会分发到mObserver.onChanged
dispatchingValue(null);
//到这里很清晰啦,如今回头看看postValue和mPostValueRunnable里的锁,和NOT_SET的做用
//1. postValue方法可能会被不少条线程调用
//2. mPostValueRunnable异步运行在主线程, 主线程是串联执行的,一次执行一个runnable
//3. 不加锁很明显不行, 多线程调用时, value从postValue方法赋值给mPendingData,
//在mPostValueRunnable主线程里把mPendingData赋值给mData,
//mPendingData和mData都是指向同一个对象, mData在主线程都是指向了最新的对象。
//在主线程队列的里mPostValueRunnable每次运行都是拿了最新的数据,有点多余
//4. 假如去掉NOT_SET, value从postValue方法赋值给mPendingData,
// 再到setValue的mData, mPendingData和mData都是指向同一个对象,
// 虽然加了锁也没用。但有了NOT_SET就不一样啦, mPendingData地址给mData,NOT_SET地址给mPendingData,
// 在postValue方法的子线程里新进来的value地址又赋值给mPendingData。
//5.看回postValue方法里 if (!postTask) { return } 这个地方,
// 假如A线程调用了postValue, 把value赋值给mPendingData并释放了锁,
// 把A.mPostValueRunnable放到主线程的Message中,
// 但这时以前的B.mPostValueRunnable还没运行完,运行到setValue方法,也没有持有锁。
// 这时B线程也调用了postValue, 这时A.mPostValueRunnable还没运行,没有把mPendingData=NOT_SET,
// B线程postTask就为false了, 接着又把value赋值给mPendingData, 接着就直接return。
// 等A.mPostValueRunnable运行时, mPendingData又被B线程更新啦。
// if (!postTask) { return } 这个判断能减小主线程不必mPostValueRunnable运行,
// 并且能更新到最新的数据。
}
private void dispatchingValue(@Nullable ObserverWrapper initiator) {
// initiator是null , 下面是遍历mObservers存储ObserverWrapper通知全部观察者
...
for (Iterator<Map.Entry<Observer<T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
// considerNotify前面分析过了,看回LiveData.observe的过程, 最终分发数据Observer.onChanged
}
}
复制代码
先说说使用ViewModel和LiveData时注意事项:
public class UserActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
...
findViewById(R.id.btn_logout).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mViewModel.onLogout(); // 点击按钮退出登陆
}
});
mViewModel = ViewModelProviders.of(this).get(UserViewModel.class);
//ViewModelProviders是一个工具类,默认包含AndroidViewModelFactory把UserViewModel.class经过反射建立ViewModel并存储在Activity中
mViewModel.getUserLiveData().observe(this, new Observer<User>() {
@Override
public void onChanged(@Nullable User user) {
//在观察者中更新UI
if(user != null){
mTvName.setText(user.name);
}else {
//没有登陆的状态
mTvName.setText("用户还没登陆!!!!!");
}
}
});
mViewModel.loadUserInfo();
}
}
public class UserViewModel extends ViewModel {
//userLiveData存储在UserViewModel
private final MutableLiveData<User> userLiveData = new MutableLiveData<User>();
public MutableLiveData<User> getUserLiveData() {
return userLiveData;
}
@Override
protected void onCleared() {
//释放资源
}
public void loadUserInfo() {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
//开启一个线程,异步操做,建议使用线程池,这里演示就直接new Thread
User user = new User();
user.name = "Albert";
userLiveData.postValue(user); // 通知数据观察者
}
}).start();
}
public void onLogout() {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
/开启一个线程,异步操做
userLiveData.postValue(null); // 通知数据观察者
}
}).start();
}
}
复制代码
介绍完例子,下面说说优势:
参考: