Jetpack学习-LiveData

个人博客

http://www.milovetingting.cn

Jetpack学习-LiveData

LiveData是什么

LiveData是一种可观察的数据存储器类,具有生命周期的感知能力。

简单使用

LiveData一般都是和ViewModel一起使用。定义一个类继承自ViewModel:

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中使用

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,然后通过调用LiveDataobserve方法添加对当前Activity的观察。

通过LiveData的setValue可以来更新数据,此时界面会自动更新。

原理

从LiveData的observe方法来看

添加observer

@MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            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。最终还是调用了LifecycleaddObserver方法。

数据更新

数据更新,是通过LiveDatasetValue方法来执行的。

@MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }

这个方法要求在主线程上执行。方法内部调用了dispatchingValue方法

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方法

 private void considerNotify(ObserverWrapper observer) {
        if (!observer.mActive) {
            return;
        }
        // Check latest state b4 dispatch. Maybe it changed state but we didn‘t get the event yet.
        //
        // we still first check observer.active to keep it as the entrance for events. So even if
        // the observer moved to an active state, if we‘ve not received that event, we better not
        // notify for a more predictable notification order.
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        //noinspection unchecked
        observer.mObserver.onChanged((T) mData);
    }

在这个方法中,最终调用了observer的onChange方法。

时序图:

数据异步更新

上面的数据更新是在UI线程上执行的,如果想要在子线程上执行,那么则需要通过postValue方法。我们也来看一下这个方法

protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            //判断mPendingData是否已经赋值
            postTask = mPendingData == NOT_SET;
            //给mPendingData赋值
            mPendingData = value;
        }
        //如果已经赋值,则取消发送
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }

这个方法是通过ArchTaskExecutor的postToMainThread方法来执行的。

先看ArchTaskExecutor.getInstance()方法

public static ArchTaskExecutor getInstance() {
        if (sInstance != null) {
            return sInstance;
        }
        synchronized (ArchTaskExecutor.class) {
            if (sInstance == null) {
                sInstance = new ArchTaskExecutor();
            }
        }
        return sInstance;
    }

再来看下构造方法

private ArchTaskExecutor() {
        mDefaultTaskExecutor = new DefaultTaskExecutor();
        mDelegate = mDefaultTaskExecutor;
    }

在这里实例化了mDefaultTaskExecutormDelegate

调用postToMainThread方法

@Override
    public void postToMainThread(Runnable runnable) {
        mDelegate.postToMainThread(runnable);
    }

执行的是DefaultTaskExecutorpostToMainThread方法

public void postToMainThread(Runnable runnable) {
        if (mMainHandler == null) {
            synchronized (mLock) {
                if (mMainHandler == null) {
                    mMainHandler = new Handler(Looper.getMainLooper());
                }
            }
        }
        //noinspection ConstantConditions
        mMainHandler.post(runnable);
    }

可以看到,其实就是post了一个runnable到主线程中。

private final Runnable mPostValueRunnable = new Runnable() {
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                //获取要更新的数据
                newValue = mPendingData;
                //mPendingData重置
                mPendingData = NOT_SET;
            }
            //noinspection unchecked
            setValue((T) newValue);
        }
    };

最终回调run方法里,还是调用的setValue方法。在run方法中,会获取要更新的数据,然后对mPendingData重置。因此,如果调用了多次postValue,如果前面的更新还没有处理,则并不会往主线程发送更新的消息,只会给mPendingData赋值,在run回调中,就会获取到最后一次的数据。

原文地址:https://www.cnblogs.com/milovetingting/p/12701436.html

时间: 2024-08-30 15:22:25

Jetpack学习-LiveData的相关文章

Jetpack学习-Lifecycle

个人博客 http://www.milovetingting.cn Jetpack学习-Lifecycle Lifecycle是什么 Lifecycle是Jetpack提供的一个组件,可以感知Activity,Fragment的生命周期变化. 简单使用 定义一个类继承自LifecycleObserver,根据业务需要,在这个类中重写相应的方法 public class LifecycleObserverImpl implements LifecycleObserver { @OnLifecycl

Jetpack系列:LiveData入门级使用方法

Android APP开发中,开发者们都想有一个公共的组件,可以实现后台数据的监听,同时实时更新到UI进行显示,从而大大简化开发过程.Google针对这一开发需求,提供了Jetpack LiveData组件.下面我们来一起看下LiveData的基本使用方法吧! 首先,先了解下使用LiveData的优点. 确保UI与数据状态匹配 不需要担心内存泄漏问题 Activity停止后数据变化不会导致Crash 不再需要人工生命周期的处理 始终使用最新的数据 正确应用配置更改 共享资源 LiveData遵循

Android Jetpack组件 - ViewModel,LiveData使用以及原理

本文涉及的源码版本如下: com.android.support:appcompat-v7:27.1.1 android.arch.lifecycle:extensions:1.1.1 android.arch.lifecycle:viewmodel:1.1.1 android.arch.lifecycle:livedata:1.1.1 什么是ViewModel, 以及工作原理 ViewModel用于存储和管理UI相关的数据,ViewModel有自己生命周期,会根据fragment,activi

Android Jetpack让Android一飞冲天

背景介绍 早在2008年,Google 推出了Android ,但那个时候 Android 刚刚问世,经过这将近11年的发展和不断优化,Android 可以说逐渐变得成熟,方便和应用越来越广. 随着 Android 手机的市场保有量越来越多,APP的研发朝着愈发的简单化,易上手的方向发展.而 Google 也是站在这一个角度出发,如何快速得让一个研发人员开发出一款APP,也可以快速的添加新的开发人员. 现在在 Google 应用市场当中,大部分 APP 已经开始使用 Android Jetpac

Android Jetpack架构组件:一文带你了解Lifecycle(使用篇)

前言 这一篇文章来介绍Android Jetpack架构组件的Lifecycle,Lifecycle用于帮助开发者管理Activity和Fragment 的生命周期,由于Lifecycle是LiveData和ViewModel的基础,所以需要先学习它. 1.为什么需要Lifecycle 在应用开发中,处理Activity或者Fragment组件的生命周期相关代码是必不可免的, 官方文档中举了一个例子,这里简化一下,在Activity中写一个监听,在Activity的不同生命周期方法中调用这个监听

安卓学习02---room

title: 安卓学习02---room date: 2020-02-02 18:20:13 tags: room是jetpack的组件,可以使程序流畅的访问sqlite. <!--more --> 1.依赖的添加 dependencies { def room_version = "2.2.2" ? implementation "androidx.room:room-runtime:$room_version" annotationProcessor

Android 架构组件 之 ViewModel 学习

Overview 今天在学习的过程中,我学了一下Android的架构组件之ViewModel的学习操作.ViewModel也是属于我们的Android Jetpack的一部风. Android 开发者文档中是这么说的: ViewModel 类旨在以注重生命周期的方式存储和管理界面相关的数据.ViewModel 类让数据可以在发生旋转等配置更改后继续存在的. 看一看我们是如何使用ViewModel的 架构组件为界面控制器提供了ViewModel 辅助程序类,该类负责为界面准备数据,在配置更改期间会

mysql学习--mysql必知必会1

?? 例如以下为mysql必知必会第九章開始: 正則表達式用于匹配特殊的字符集合.mysql通过where子句对正則表達式提供初步的支持. keywordregexp用来表示后面跟的东西作为正則表達式处理. (.)是正則表達式的一个符号,表示匹配随意一个字符: mysql> select prod_name -> from products -> where prod_name regexp '.000' -> order by prod_name; +--------------

mysql学习--mysql必知必会

上图为数据库操作分类: 以下的操作参考(mysql必知必会) 创建数据库 执行脚本建表: mysql> create database mytest; Query OK, 1 row affected (0.07 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | mytest | | performan