个人博客
http://www.milovetingting.cn
Jetpack学习-LiveData LiveData是什么 LiveData是一种可观察的数据存储器类,具有生命周期的感知能力。
简单使用 LiveData
一般都是和ViewModel一起使用。定义一个类继承自ViewModel
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class LiveDataSub extends ViewModel { private MutableLiveData<String> infos; private int number; public MutableLiveData<String> getInfo () { if (infos == null ) { infos = new MutableLiveData <>(); } return infos; } public int increaseNumber () { number++; return number; } }
在这个类里定义MutableLiveData
类型的属性,并提供外界访问的方法getInfo
在Activity中使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public class LiveDataActivity extends AppCompatActivity { private TextView tv; private LiveDataSub viewModel; @Override protected void onCreate (@Nullable Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_livedata); tv = findViewById(R.id.tv); viewModel = ViewModelProviders.of(this ).get(LiveDataSub.class); viewModel.getInfo().observe(this , new Observer <String>() { @Override public void onChanged (String s) { tv.setText(s); } }); } public void update (View view) { String info = "info:" + viewModel.increaseNumber(); viewModel.getInfo().setValue(info); } }
通过ViewModelProviders.of(this).get(LiveDataSub.class
)来实例化刚才定义的ViewModel
,然后通过调用LiveData
的observe
方法添加对当前Activity的观察。
通过LiveData的setValue
可以来更新数据,此时界面会自动更新。
原理 从LiveData的observe方法来看
添加observer 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @MainThread public void observe (@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) { assertMainThread("observe" ); if (owner.getLifecycle().getCurrentState() == DESTROYED) { return ; } LifecycleBoundObserver wrapper = new LifecycleBoundObserver (owner, observer); ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper); 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); }
observe方法的调用要求是在主线程。如果Activity对应的lifecycle已经处于DESTROYED
状态,则会直接返回,不添加observer。最终还是调用了Lifecycle
的addObserver
方法。
数据更新 数据更新,是通过LiveData
的setValue
方法来执行的。
1 2 3 4 5 6 7 @MainThread protected void setValue (T value) { assertMainThread("setValue" ); mVersion++; mData = value; dispatchingValue(null ); }
这个方法要求在主线程上执行。方法内部调用了dispatchingValue
方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 void dispatchingValue (@Nullable ObserverWrapper initiator) { if (mDispatchingValue) { mDispatchInvalidated = true ; return ; } mDispatchingValue = true ; do { mDispatchInvalidated = false ; if (initiator != null ) { considerNotify(initiator); initiator = null ; } else { for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator = mObservers.iteratorWithAdditions(); iterator.hasNext(); ) { considerNotify(iterator.next().getValue()); if (mDispatchInvalidated) { break ; } } } } while (mDispatchInvalidated); mDispatchingValue = false ; }
由于之前传入的ObserverWrapper
为null,因此会执行下面的迭代里的considerNotify
方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 private void considerNotify (ObserverWrapper observer) { if (!observer.mActive) { return ; } if (!observer.shouldBeActive()) { observer.activeStateChanged(false ); return ; } if (observer.mLastVersion >= mVersion) { return ; } observer.mLastVersion = mVersion; observer.mObserver.onChanged((T) mData); }
在这个方法中,最终调用了observer的onChange
方法。
时序图:
数据异步更新 上面的数据更新是在UI线程上执行的,如果想要在子线程上执行,那么则需要通过postValue
方法。我们也来看一下这个方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 protected void postValue (T value) { boolean postTask; synchronized (mDataLock) { postTask = mPendingData == NOT_SET; mPendingData = value; } if (!postTask) { return ; } ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable); }
这个方法是通过ArchTaskExecutor的postToMainThread
方法来执行的。
先看ArchTaskExecutor.getInstance()
方法
1 2 3 4 5 6 7 8 9 10 11 public static ArchTaskExecutor getInstance () { if (sInstance != null ) { return sInstance; } synchronized (ArchTaskExecutor.class) { if (sInstance == null ) { sInstance = new ArchTaskExecutor (); } } return sInstance; }
再来看下构造方法
1 2 3 4 private ArchTaskExecutor () { mDefaultTaskExecutor = new DefaultTaskExecutor (); mDelegate = mDefaultTaskExecutor; }
在这里实例化了mDefaultTaskExecutor
和mDelegate
调用postToMainThread
方法
1 2 3 4 @Override public void postToMainThread (Runnable runnable) { mDelegate.postToMainThread(runnable); }
执行的是DefaultTaskExecutor
的postToMainThread
方法
1 2 3 4 5 6 7 8 9 10 11 public void postToMainThread (Runnable runnable) { if (mMainHandler == null ) { synchronized (mLock) { if (mMainHandler == null ) { mMainHandler = new Handler (Looper.getMainLooper()); } } } mMainHandler.post(runnable); }
可以看到,其实就是post了一个runnable
到主线程中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 private final Runnable mPostValueRunnable = new Runnable () { @Override public void run () { Object newValue; synchronized (mDataLock) { newValue = mPendingData; mPendingData = NOT_SET; } setValue((T) newValue); } };
最终回调run方法里,还是调用的setValue
方法。在run方法中,会获取要更新的数据,然后对mPendingData重置。因此,如果调用了多次postValue,如果前面的更新还没有处理,则并不会往主线程发送更新的消息,只会给mPendingData赋值,在run回调中,就会获取到最后一次的数据。