LiveData介绍

LiveData 是一个可以被查询的数据持有类,它可以感知 Activity、Fragment或Service 等组件的生命周期。在底层数据更改时奉告视图,言外之意便是数据一经更改,就去奉告视图去更新数据。

LiveData利益

  1. 实时数据改写,实时更新UI
  2. 防止呈现内存走漏问题android手机
  3. 防止了由Activity处于stop状况而引起的溃散
  4. 屏幕产生旋转或收回时也能当即取到数据
  5. 防止了界面由生命周期而呈现的问题

LiveData运用进程

  • 在ViewModel中创立一个持有某种数据类型的LiveData ,通常是用子类MutableLiveData界android下载装置
  • 经过 observe 办法可以订阅修改数据的奉告
  • 经过 postValue()或许 setValue() 办法发送事情更新数据
  • 现已订阅的 Obsappearanceerver 就APP可以得到数据更改时的奉告并GitHub回调 onChanged() 办法
  • 在onChanged()办法中更新数据更新UI

LiveData简略运android的drawable类

        //查询者人物
myViewModel.getData().observe(this, new Observer<String>() {
@Override
public void onChanged(Str缓存和下载的差异ing data) {缓存视频兼并
mainBinding.textVie源码编辑器编程猫下载w.setText(data);
}
});
//被查询者人物
mainBinding.textView.setOnClickListener(new View.OnClickList源码年代ener(github下载) {
@Override源码超市
public void onClick(View view) {
myViewModel.getDa缓存视频怎样转入相册ta().setValue("狗哥很帅`!"app装置下载);`
}
});

缓存码剖析

LiveData中的observe()源码解析

先看看LiveData中observe()办法的参数源码站

    @MainThread
public void observe(@NonNull LifecycleOwner owner缓存视频兼并, @NonNull Observer<? super T> observer) {
}

考虑

咱们看到LiveData源码中ob源码站serve()办法第一个参数是 LifecycleOwner,而咱们代码中传递的是当时页面上下文this源码编辑器编程猫下载,为什么不会报android下载错 ?this 和 LifecycleOwandroid体系ner 有何联系呢 ?

剖析

咱们看当时 MainActivity承继自github永久回家地址 AppCompatActivity

public class MainActiviapplety extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}

再看看AppCompatActivity,

public class AppCompatActivity extends FragmentActivity implements AppCompatCandroid最新版别allback,
TaskStackBuilder.SupportParentab缓存视频怎样转入相册le, ActionBarDrawerToggle.DelegateProvider {
}

发现AppCompatActivity又承继自FragmentActivity,在持续看看FragmentActivity是什么东西:

public clas缓存视频变成本地视频s FragmentActivigithub是干什么的ty extends ComponentActivity implemapplicationents
ActivityCompat.OnRequestPermissio源码共享网nsResappointmentultCandroid是什么手机牌子allback,
ActivityCompat.RequestPermissi缓存和下载的差异onsRequestCodeValidator {

又发现FragmentActivity承继自源码编辑器编程猫下载ComponentActivity,这源码本钱时分哥哥们可能会有些不耐烦了,稳住稳住,立刻就到了:

public class ComponentActivity extends andr源码本钱oidx.core.app.ComponentActivity implements
LifecycleOwner,
ViewModAndroidelStoreOwner,
HasDefaultViewModelProviderFactory,
SavedStateRegistryOgithub永久回家地址wner,
OnBackPressegithub敞开私库dDispatcherOwner {}
}

这时分咱们发现了,MainActivity 的终极父类其实是完成了 Lifecandroid软件开发ycleOwner 的接口,所以传递this不会报错。而observe()的第一个参数其实就相当于一个被查询者,第二个参数observer就相当于查询者。

剖析完observeandroid软件开发()的结构办法,接下来咱们看看observe()appreciate办法做了哪些操作:

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Obse缓存视频rver<? super T> observer) {
assertMainThread("observe");
ifandroid软件开发 (owner.getLifec缓存视频怎样转入相册ycandroid体系le().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wragithub永久回家地址pper = new LifecycleBoundObserver(owner, obapp装置下载servergithub永久回家地址);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null &approachamp;& !existing.isAttachedTo(owner)) {
throw new IllegalArgumentExceptiandroid下载o缓存视频兼并n(源码编辑器编程猫下载"Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
owner.getLifecycle().addObserver(wrapper);
}
1. assertMainThread(“observe”);
assertMain缓存和下载的差异Thread("observe"appreciate);
 static void assertMainThread(String methodName) {
if (!ArchTaskExecutor.getInstance().isMainThread()) {
throw newgithub怎样读 IllegalStateException("Cannot invoke " + methodName + " on a background"
+ " threagithubcom1jie1小可爱d");
}
}

咱们可以查看他的源码发现:
这个个办法中判别了当时线程是否为主线程,假定githubcom1jie1小可爱不是主线程则抛出反常

2.源码买卖网站源码 if()判别生命周期状况
if (owandroid下载装置ner.getLifecycle().getCurrentState() == DESTROYED) {
return;
}

经过owner获取到当时页缓存视频在手机哪里找面的生命周期状况是否被毁掉,假定毁掉则return,可以防止内存走漏的状况

3. LifecycleBoundObserver装饰器
 LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);

相当于一个装饰器,将持有者(被查询github是干什么的者Activity)和查询者都装进去

LifecycleBou源码共享网ndObserver源码

        @Override
public void onStateChang源码之家e缓存视频在手机哪里找d(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
//假定前页面的生命周期状况是否被毁掉,假定毁掉则removeObserver(mObserver)android下载装置,即移除Observerappreciate;
if (mOwner.getL缓存和下载的差异ifecycle().getCurrentState()源码年代 == DESTROYED) {
removeObserver(mObserver);appstore
return;
}
actappleidiveStateChanged(shouldBeActive());
}
4. ObserverWrapper缓存
Obse源码编辑器rverWrapper existing = mObservers.putIfAbsent源码怎样做成app软件(observer, wrapper);

mObservers源码

 private SafeIterableMap<Observe源码之家r源码之家<? super T>, ObserverWrapper> mObservers =
new SafeItandroid体系erableMap<>();

mObservers是一缓存视频变成本地视频个Map,相缓存视频在手机哪里找当于缓存,缓存一份装饰器,key缓存视频兼并为oandroid软件开发bserver,value为装饰器wrapper

总结

整个LiveData都是时刻去查询生命周期的状况,然后从根源上防止了内存走漏的呈现,这也是现在许多公司选用jetpack的原因

LiveData中setValu源码买卖网站源码e()源源码本钱码解析

这儿我仍是重复放一下运用的那段代码吧,也便于大佬们更好的剖析,大佬们莫怪!

       //查询者人物
myView缓存文件在哪里Model.getData().observe(this, new Observegithub中文官网r<String>() {
@Override
public void onChanged(String datandroid平板电脑多少钱a) {
mainBinding.textView.setText(data);
}
});
//被查询者人物github永久回家地址
mainBinding.textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
myViewModel.getData().setValue("哈哈哈哈");
}
});

考虑

查询者是怎样监听到被查询者的数据实时改动呢?

剖析

咱们来看被查询github-zookeeper者的触发进程:

 myViewModel.getData().setValue("哈哈哈哈");

这儿发现其实是经过setValue()办法进行触发的,那咱们进去看缓存视频变成本地视频看这个setValue()办法:

@缓存的视频怎样保存到本地SuppressWarnings("WeakerAccess")
public class MutableLiveData<T> extends LiveData<T> {
@Override
p缓存视频ublic void po源码超市stVaappointmentlue(T value) {
super.postValue(value);
}
@Ove缓存视频在手机哪里找rride
public void setValue(T value) {
super.setValue(value);
}
}

经过super.setValue(value),调用父类的seandroid的drawable类tValue(),将 value 传入,即 LiveData源码本钱 的setValue(value)办法。
咱们持续看看 super.setValue(value)办法:

 @MainThreandroid最新版别ad
protected void setValue(T value) {
//这儿又一次判别了是否为主线程,假定不是主线程,则抛出反常
as源码编辑器编程猫下载sertMainThread("setValue");
mVersion+缓存视频怎样转入本地视频+;
//将valuapplicatione赋值给d源码买卖网站源码ata
mData = value;
//分发value,
disgithub是干什么的patchingValue(null);
}
mVersion

LiveData内维护的mVersion标明的是发送信息的版appearance别,每次发送一次信息, 它都会+1, 而Ogithub中文官网bserverWrapper内维护的github怎样下载文件mLastVersion为订阅触发的版别号, 当订阅动作生效的时分, 它的版别号会和发送信息的版别号同步.他们初始值都为-1。

考虑

dispatchingValue(null) 参数传递 null 有何意义呢 ?

剖析

咱们持续查看disappleidpatchingValue()的源码

 @SuppressWarnings("WeakerAccess") /* synthetic access */
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvapplicationalidated = true;
return;
}
mDispatchingV源码超市alandroid的drawable类ue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
for (Iterator<Map.Entry<ObsAndroiderver<? super T>, ObserappreciateverWrappeandroid最新版别r>> iterator =
mObservers.iter源码怎样做成app软件atandroid最新版别orWithAdditiogithubcom1jie1小可爱ns(); iterator.hasNext(); ) {
considerNotify(iterator.源码站next().源码共享网getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mD源码超市ispatchInvalidated);
mDispatchingValue = false;
}

这儿咱们首要剖析这段代码:

 for (Iterator<Map.Entry缓存视频兼并软件<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWigithub官网thAdditions(); iterator.hasandroid的drawable类Next(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidatedandroid平板电脑多少钱) {
break;
}
}

当咱们有多个被查询者时,android什么意思遍历一切的查询者并取出查询者:即:

new Observeandroid下载r<String>() {
@Override
public void onChanged(String data) {
mainBinding.textView.setText(data);
}
}

然后经过considerNotify唤醒

considerNotify()
 @SuppressWarn源码共享网ings("unche源码编辑器编程猫下载cked"缓存视频怎样转入相册)
private void consiAPPderNotify(ObserverWrapper observer) {
if (!observer.mActiv源码编辑器编程猫下载e) {
r源码买卖网站源码eturn;
}
if (!obserandroid软件开发ver.shouldBeActive()源码之家) {
observer.activeStateChanged(false);android手机
return;
}
if (observer.mLastVersion >= mVergithub敞开私库sion) {
returnandroid下载;
}
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
if (!observer.mActive) {
return;
}

这个判别什么意思呢?

假定 observer.mActive ==true , 则咱们的当时页面时可见状况,即处于 on缓存文件在哪里Resume() 状况,而这儿是 !observer.mActive,源码怎样做成app软件即当时页面处于不行见的状况,然后 reappreciateturn ;

这样做的优点是又一次的去防止了内存的走漏;

举个比如

举个栗子:假定咱们刚发动Activity,然后敏捷的封闭掉Activity,这时分刚翻开这个Activity的时分现已发起了网络央求,然后要去央求数据并奉告界面去改写UI,这时分就会走considerNotify办法去奉告控件,而当页面封闭的话,是找不到控件的,这时分就会引发缓存文件在哪里溃散问题,所以这儿这个判别又一github敞开私库次的判别了当时页面是否处于可见状况,假定为可见状况则去onCappointmenthanged数据,假定不行见则直接return,也然后防止了溃散和内存走漏的问源码共享网题!

 observer.mObserver.onChanged((T) mData);

mData即为改动的数据,经过mObserver调用onChange(mData),这时分数据 data 就回到了 onChanged()办法中了。

//查询者人物
myViewModel.getData().observe(this, new Obse缓存视频兼并rver<String>() {
@Override
public void onChanged(String data) {
//数据就回到了这儿的onChanged办法
mainBinding.textView.setText(data);
}
});

总结

  1. LiveData 内部完成了查询者形式,假定数据github是干什么的要一起奉告几个界面,可以采纳这种办法
  2. LiveData 数据改动的时分,会回调 Observer 的 onChange 办法,但是回调的条件是 lifecycleOwner(即所依托的 Activity 或许 Fragmentandroid什么意思appear 处于 onSandroid什么意思tart() 或许 onResu源码年代me() 状况,它源码站才会回调,不然,有必要比及 lifecycleOwner 切换到前台的时分,才回调,其内部处理了因为Lifecycle而导致github是干什么的的溃散,内存走漏等问题。因此,这对功能方面确实是一个不小的提高。

传送门

这是我写的一个基于ViewModel + Lgithub永久回家地址iveData+ DataBindgithub是干什么的ing、多语言化、矢量图、束缚性布局的篮球计分器的一个学习的简略Demo

github.com/SmartTwoDog…