LiveData简介 本质上是一个观察者模式,在Activity/Fragment中实现观察者,LiveData是被观察者,在LiveData存储的数据变更时触发事件。
LiveData还具有生命周期感知 能力,可以控制在应用可见时去更新UI,不可见时不执行操作,减少了内存泄露问题。
LiveData示例 一般情况下LiveData
要配合着ViewModel
一起使用,ViewModel负责触发数据更新,LiveData负责通知观察者数据更新。
引入LiveData三方库
1 2 3 4 5 dependencies { def lifecycle_version = "2.0.0" implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version" }
新建ViewModel类并包含LiveData
1 2 3 4 5 6 7 8 9 10 public class LiveDataViewModel extends ViewModel { private MutableLiveData<String> currentText; public MutableLiveData<String> getCurrentText () { if (currentText == null ) return new MutableLiveData<>(); return currentText; } }
在Activity/Fragment中添加监听
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 26 27 28 29 30 public class NewActivity extends AppCompatActivity { private LiveDataViewModel viewModel; private TextView textView; private Button button; @Override protected void onCreate (@Nullable Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = findViewById(R.id.text); button = findViewById(R.id.btn1); viewModel = ViewModelProviders.of(NewActivity.this ).get(LiveDataViewModel.class ) ; final Observer<String> testObserver = new Observer<String>() { @Override public void onChanged (String s) { textView.setText(s); } }; viewModel.getCurrentText().observe(this , testObserver); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick (View v) { viewModel.getCurrentText().setValue("12" + System.currentTimeMillis()); } }); } }
这样即可以实现监听功能。
想了解更多实例可参考LiveData官方示例
LiveData源码解析 LiveData 1 2 3 public abstract class LiveData <T > { ... }
LiveData
是一个抽象类无法直接使用,一般都是应用其子类MutableLiveData
1 2 3 4 5 6 7 8 9 10 11 public class MutableLiveData <T > extends LiveData <T > { @Override public void postValue (T value) { super .postValue(value); } @Override public void setValue (T value) { super .setValue(value); } }
MutableLiveData
多了设置数据的方法,以便开发者对内容进行修改。若不想有人进行修改,可以返回LiveData
保证安全。
Observer 构建LiveData完毕后,需要对其添加监听。
1 2 3 4 5 6 7 public interface Observer <T > { void onChanged (T t) ; }
Observer
只提供数据变化的监听并返回修改后的结果。
LiveData.java 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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers = new SafeIterableMap<>(); @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); } @MainThread public void observeForever (@NonNull Observer<? super T> observer) { assertMainThread("observeForever" ); AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer); ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper); if (existing != null && existing instanceof LiveData.LifecycleBoundObserver) { throw new IllegalArgumentException("Cannot add the same observer" + " with different lifecycles" ); } if (existing != null ) { return ; } wrapper.activeStateChanged(true ); }
当宿主组件已经Destroy时,就无需添加监听
需要新建一个LifecycleBoundObserver
保存owner以及observer
从mObservers.putIfAbsent()
中去获取或者插入对应observer
返回为null,则对owner
添加该监听。
LifecycleBoundObserver LiveData.java 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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 protected void onActive () {}protected void onInactive () {}private abstract class ObserverWrapper { final Observer<? super T> mObserver; boolean mActive; int mLastVersion = START_VERSION; ObserverWrapper(Observer<? super T> observer) { mObserver = observer; } abstract boolean shouldBeActive () ; boolean isAttachedTo (LifecycleOwner owner) { return false ; } void detachObserver () { } void activeStateChanged (boolean newActive) { if (newActive == mActive) { return ; } mActive = newActive; boolean wasInactive = LiveData.this .mActiveCount == 0 ; LiveData.this .mActiveCount += mActive ? 1 : -1 ; if (wasInactive && mActive) { onActive(); } if (LiveData.this .mActiveCount == 0 && !mActive) { onInactive(); } if (mActive) { dispatchingValue(this ); } } }class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver { @NonNull final LifecycleOwner mOwner; LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) { super (observer); mOwner = owner; } @Override boolean shouldBeActive () { return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED); } @Override public void onStateChanged (LifecycleOwner source, Lifecycle.Event event) { if (mOwner.getLifecycle().getCurrentState() == DESTROYED) { removeObserver(mObserver); return ; } activeStateChanged(shouldBeActive()); } @Override boolean isAttachedTo (LifecycleOwner owner) { return mOwner == owner; } @Override void detachObserver () { mOwner.getLifecycle().removeObserver(this ); } }
发布修改 设置数据完毕后,需要通知到监听者进行响应
LiveData.java 1 2 3 4 5 6 7 8 public abstract class LiveData <T > { protected void setValue (T value) ; protected void postValue (T value) ; }
postValue()及setValue()
都是protected
只有本身及子类才可以调用,又由于LiveData
为abstract
不可用new
即使用子类才可以修改数据。
setValue():同步调用 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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 private volatile Object mData = NOT_SET; @MainThread protected void setValue (T value) { assertMainThread("setValue" ); mVersion++; mData = value; dispatchingValue(null ); }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 ; } 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); }
源码简述 调用setValue()
:
先监测当前是否在主线程运行,否则抛出异常结束运行
设置当前存储的mVersion+1
,以待后用
调用dispatchValue()
进行数据分发
首先判断当前是否存在循环调用,在dispatchValue()
中设置mDispatchingValue
为true,操作结束完毕再设置false。还有一个mDispatchInvalidated
标志位,如果该标志为true,表明已经发生了循环调用,需要重新开始。
considerNotify()
将消息发送到对应的观察者上,需要判定当前是否是因为调用setValue()
导致的分发,因为在UI不可见时也不会调用分发,只有可见时才会调用,就可能导致重复分发,需要使用到mVersion
来进行一次判定,如果小于记录的mVersion
。即进行分发结束一次分发过程。
当Activity/Fragment挂在后台时,LiveData不会分发数据,setValue()
的值就会被缓存到mData
中,但是只能缓存一个值,所以当再次回到前台时,最终打到的就是最新的一次setValue()
的数据。
postValue():异步调用 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 26 27 28 29 private volatile Object mPendingData = NOT_SET;private final Runnable mPostValueRunnable = new Runnable() { @Override public void run () { Object newValue; synchronized (mDataLock) { newValue = mPendingData; mPendingData = NOT_SET; } setValue((T) newValue); } }; protected void postValue (T value) { boolean postTask; synchronized (mDataLock) { postTask = mPendingData == NOT_SET; mPendingData = value; } if (!postTask) { return ; } ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable); }
postValue()
利用ArchTaskExecutor
将发送消息逻辑切换到主线程上,实质执行的还是setValue()
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class ArchTaskExecutor extends TaskExecutor { private static volatile ArchTaskExecutor sInstance; @NonNull private TaskExecutor mDefaultTaskExecutor; private ArchTaskExecutor () { mDefaultTaskExecutor = new DefaultTaskExecutor(); mDelegate = mDefaultTaskExecutor; } @Override public void postToMainThread (Runnable runnable) { mDelegate.postToMainThread(runnable); } }
archTaskExecutor
实质调用的是DefaultTaskExecutor
去执行切换主线程任务
DefaultTAskExecutor.java 1 2 3 4 5 6 7 8 9 10 11 12 13 @Override public void postToMainThread (Runnable runnable) { if (mMainHandler == null ) { synchronized (mLock) { if (mMainHandler == null ) { mMainHandler = new Handler(Looper.getMainLooper()); } } } mMainHandler.post(runnable); }
通过Handler
进行了主线程切换。
源码简述 postValue()
调用过程:
先根据mPendingData
的值判定是否需要执行任务,当已有任务在执行时,不需要重复执行
调用ArchArchTaskExecutor
实质调用了DefaultTaskExecutor
去执行postToMainThread()
本质通过Handler
进行了线程切换任务
最后切换主线程完毕后,去调用setValue()
发送数据
LiveData拓展
根据源码分析,LiveData的数据接受的生命周期只在onStart()
-> onPause()
中,其他时间无法分发消息,只有等到回到用户可见时重新开始分发过程。
LiveData
是通过Lifecycle
与Activity/Fragment进行生命周期绑定的。
由于LiveData
是与生命周期进行绑定的,即使宿主被销毁,也不会造成内存泄露。
内容引用 Jekton-LiveData
LiveData的工作原理