当前位置: 首页 > news >正文

公司网站做的比较好/推广软件哪个好

公司网站做的比较好,推广软件哪个好,西安网站制作网站,用哪个平台做网站好LiveData 是 Google 推荐的基于观察者的数据持有者,可以认为是一个轻量级的RxJava。 一般来说不会单独使用,会和其他组件一起搭配,最常用的就是 ViewModel 了。 目录1. 概述1.1 什么是LiveData1.2 为什么使用LiveData2. 使用2.1 基本用法2.2 …

LiveData 是 Google 推荐的基于观察者的数据持有者,可以认为是一个轻量级的RxJava。
一般来说不会单独使用,会和其他组件一起搭配,最常用的就是 ViewModel 了。

目录

  • 1. 概述
    • 1.1 什么是LiveData
    • 1.2 为什么使用LiveData
  • 2. 使用
    • 2.1 基本用法
    • 2.2 更改 LiveData 中的数据
      • 2.2.1 Transformations.map 方法
      • 2.2.2 Transformations.switchMap 方法
      • 2.2.3 MediatorLiveData合并数据源
      • 2.2.4 自定义LiveData
  • 3. 原理
    • 3.1 LiveData 如何观察生命周期变化
    • 3.2 LiveData 的 observe 方法回调
    • 3.3 postValue 方法
    • 3.4 总结
  • 参考文章

1. 概述

1.1 什么是LiveData

官方定义:

LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData具有生命周期感知能
力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可
确保 LiveData仅更新处于活跃生命周期状态的应用组件观察者。

简单可以理解为一个 Observable ,同时能够感知生命周期

如果搭配ViewModel,那么 ViewModel 就是 LiveData 的数据源,当数据更新后, LiveData 就会通知它的所有观察者。 与 RxJava 的方法不同的是, LiveData 并不是通知所有观察者,他只会通知处于 Active 状态的观察者,如果一个观察者处于 Paused 状态或 Destroyed 状态,那么它将不会受到通知。

1.2 为什么使用LiveData

  1. 解耦
  2. 避免内存泄漏

Activity、Service、Fragment可以安全的观察LiveData对象,而且不用在 onPaused 或者 onDestroy 方法中去解订阅。
一旦观察者恢复 resumed 状态, 它将会重新收到 LiveData 的最新数据。

2. 使用

这里省去导入流程,可以看 Jetpack学习之 Lifecycle

2.1 基本用法

LiveData 是一个抽象类, 它有一个比较简单又常用的实现类:MutableLiveData, 这里举个栗子:

class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val mutableLiveData = MutableLiveData<String>()// 1mutableLiveData.observe(this, Observer { Log.d(TAG, "onChanged: $it")})// 2mutableLiveData.postValue("Hi Noel~")}
}

注释1:observe() 有两个参数,分别是 LifecycleOwnerObserver<T> 也就是被观察者。
Kotlin代码的lambda表达式省略掉了其实现方法体,也就是 onChanged(@Nullable final String s) 方法,他能够在数据变化时,回调这个方法

注释2:postValue() 会在主线程更新数据,这样就会得到打印的结果,如下所示:
在这里插入图片描述
这里需要注意的是:

  • 将更新界面的LiveData对象存储在ViewModel中,而不是将其存储在Activity或Fragment中:
    (1)避免Activity或Fragment过于庞大,分离 ui 和数据
    (2)将LiveData实例与特定Activity实例分离开,使LiveData对象在配置更改后继续存在
  • 在onCreate方法中开始观察LiveData对象
    不要在onResume方法中进行调用 observe() ,因为会出现多次调用的问题。
    确保Activity或Fragment变为活跃状态后具有可以立即显示的数据,因为应用组件处于STARTED 状态,就会从它正在观察的 LiveData 对象接收最新值
  • 当组件处于DESTROY状态时会自动取消订阅
  • 除了使用 postValue(),还可以使用 setValue(),区别是后者必须在主线程调用。如果需要在子线程中更新 LiveData, 可以使用 postValue 方法。

2.2 更改 LiveData 中的数据

2.2.1 Transformations.map 方法

和 RxJava 一样,我们可以对数据分发到指定对象之前,给它map一下,转化成另一种数据,比如下面代码,LiveData 原数据是 Int 型, 通过 map 转化成 String 类型(或则任何数据):

    override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val mutableLiveData = MutableLiveData<Int>()mutableLiveData.observe(this, Observer {Log.d(TAG, "onChanged1: $it")})val transformationsLiveData = Transformations.map(mutableLiveData) { input ->("$input go")}transformationsLiveData.observe(this, Observer {Log.d(TAG, "obChanged2: $it")})mutableLiveData.postValue(1)}

2.2.2 Transformations.switchMap 方法

和 map 不同, switchMap返回的结果必须是一个 LiveData 数据,而且它可以通过一个 Boolean 值来选择监听对象

    override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)mutableLiveData1 = MutableLiveData()mutableLiveData2 = MutableLiveData()// 1liveDataSwitch = MutableLiveData()// 如果是true,选择监听1,否则监听2val transformedLiveData = Transformations.switchMap(liveDataSwitch) {if (it) mutableLiveData1 else mutableLiveData2}transformedLiveData.observe(this, Observer {Log.d(TAG, "onChanged: $it")})liveDataSwitch.postValue(false)mutableLiveData1.postValue("noel")mutableLiveData2.postValue("bye")}

注释1:创建一个 MutableLiveData<Boolean> 来控制切换并复制给 liveDataSwitch
当 liveDataSwitch 的值为 true 时, 返回 mutableLiveData1, 否则返回 mutableLiveData2
这样最终输出的结果为2

2.2.3 MediatorLiveData合并数据源

MediatorLiveData 继承自 MutableLiveData, 它的作用是可以收集多个 LiveData。 如果其中一个 LiveData 数据源发生变化,那么也会通知到 MediatorLiveData

    override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val mutableLiveData1 = MutableLiveData<String>()val mutableLiveData2 = MutableLiveData<String>()// 创建一个用于合并数据源的LiveDataval liveDataManager = MediatorLiveData<String>()// 添加数据 LiveData1, 并监听其变化liveDataManager.addSource(mutableLiveData1) {Log.d(TAG, "onChanged 1: $it")}// 添加数据 LiveData2, 并监听其变化liveDataManager.addSource(mutableLiveData2) {Log.d(TAG, "onChanged 2: $it")}liveDataManager.observe(this, Observer {Log.d(TAG, "onChanged Data: $it")})mutableLiveData1.postValue("i always like u")liveDataManager.postValue("thank u")}

打印结果:
在这里插入图片描述

2.2.4 自定义LiveData

我们可以自定义一个 LiveData, 因为会有观察者来观察这个 LiveData, 所以观察者处于 STARTED 或者 RESUMED 时,LiveData 将会处于 Activity状态,这个时候通过实现 onActive() / onInactive() 来通知观察者。

下面是个例子,我们设定一个可以变化的数据类:

class ExtStringLiveData private constructor() : LiveData<String>() {companion object {private const val TAG = "ExtStringLiveData"private var sInstance: ExtStringLiveData? = null@MainThreadfun get(): ExtStringLiveData? {if (sInstance == null) {sInstance = ExtStringLiveData()}return sInstance}}// 观察者处于活跃状态, 则通知它override fun onActive() {Log.d(TAG, "onActive")// 这里的数据是写死的, 在实际项目中, 可以以监听器不断输出数据value = "if u find me again, i will with u again"}override fun onInactive() {Log.d(TAG, "onInactive")// 这里的数据是写死的, 在实际项目中, 可以以监听器不断输出数据// 在这之后, 就不会再想观察者发送数据直到观察者恢复active状态, 所以这一里在更改数据就不会通知了value = "because I'm starting to regret it"}
}

然后在 MainActivity 去监听它:

    override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)ExtStringLiveData.get()?.observe(this, Observer {Log.d(TAG, it)})}

打印结果为:

在这里插入图片描述
而在 LiveData 的 onInactive() 中更改的string数据, MainActivity 就打印不出来了。

3. 原理

3.1 LiveData 如何观察生命周期变化

因为组件都是通过调用 LiveData.observe(LifecycleOwner, Observer<? super T>) 进行监听,所以了解 Livecycle 的同学肯定就知道了其中的奥秘。我们来看看它的源码吧:

    @MainThreadpublic void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {assertMainThread("observe");// 1if (owner.getLifecycle().getCurrentState() == DESTROYED) {return;}// 2LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);// 3ObserverWrapper 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;}// 4owner.getLifecycle().addObserver(wrapper);}

注释1:如果当前声明周期是 DESTORYED, 则拒绝注册

注释2:新建一个 LifecycleBoundObserver 实例,并传入相应参数

注释3:mObservers 的类型是 SafeIterableMap<Observer<? super T>, ObserverWrapper>mObservers,key是观察者,value是注释2中创建的对象。
在这个map中的putIfAbsentput 是有区别的,如果传入的 key 存在,就返回value,而不替换,如果 key 不存在,则添加进去,并返回null。

注释4:如果注释3的map中没有数据, 则调用 Lifecycle.addObserver,传入的是 LivecycleBoundObserver。 看来这个类比较重要,我们有必要去了解它的构造和作用。

3.2 LiveData 的 observe 方法回调

来看看 LivecycleBoundObserver ,它是 LiveData 的内部类:

    class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {@NonNull final LifecycleOwner mOwner;...@Overrideboolean shouldBeActive() {return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);}@Overridepublic void onStateChanged(@NonNull LifecycleOwner source,@NonNull Lifecycle.Event event) {Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();if (currentState == DESTROYED) {removeObserver(mObserver);return;}Lifecycle.State prevState = null;while (prevState != currentState) {prevState = currentState;// 1activeStateChanged(shouldBeActive());currentState = mOwner.getLifecycle().getCurrentState();}}@Overrideboolean isAttachedTo(LifecycleOwner owner) {return mOwner == owner;}@Overridevoid detachObserver() {mOwner.getLifecycle().removeObserver(this);}}

该类继承了 ObserverWrapper 类,重写了 shouldBeActive() 方法, 它的作用是用来判断当前传入的组件是否是 Active的, Active状态包括 STARTED 、 RESUMED

该类还实现了 LifecycleEventObserver 接口,当组件状态发生变化的时候, 会调用 onStateChanged() ,当组件处于 DESTORYED 状态是,会调用 removeObserver() 来移除 observer。
这也就是为什么,LiveData 不会给那些 Inactive 的组件发通知。

注释1: 调用父类的 activeStateChanged(),我们来看看父类:

    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;changeActiveCounter(mActive ? 1 : -1);if (mActive) {// 1dispatchingValue(this);}}}

ObserverWrapper 是一个抽象类,它包装了一个 Observer, activeStateChanged 会看 传进来的状态是否和此前状态是否相同,不同则,则执行 changeActiveCounter() ,来更新一下当前LiveData 观察者的活跃与非活跃的数量, 来决定调用 onActive()onInactive()

其次,如果当前是 Active 状态,则调用注释1的 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;}

如果当前处于可分发状态, 则会调用 considerNotify() 方法:

    private void considerNotify(ObserverWrapper observer) {if (!observer.mActive) {return;}if (!observer.shouldBeActive()) {observer.activeStateChanged(false);return;}if (observer.mLastVersion >= mVersion) {return;}observer.mLastVersion = mVersion;// 1observer.mObserver.onChanged((T) mData);}

即使是到了这里,也会一直在判断当前组件的状态,非常严格呢。

如果所有更新条件都满足,则会调用 Observer 的 onChanged() , 也就从这里回调出去了~

3.3 postValue 方法

我们来看看调用 postValue() / setValue() 之后,LiveData 做了什么事情, 这里以 postValue 为例,来看看代码~

    protected void postValue(T value) {boolean postTask;synchronized (mDataLock) {postTask = mPendingData == NOT_SET;mPendingData = value;}if (!postTask) {return;}// 1ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);}private final Runnable mPostValueRunnable = new Runnable() {@SuppressWarnings("unchecked")@Overridepublic void run() {Object newValue;synchronized (mDataLock) {newValue = mPendingData;mPendingData = NOT_SET;}// 2setValue((T) newValue);}};// 3@MainThreadprotected void setValue(T value) {assertMainThread("setValue");mVersion++;mData = value;// 4dispatchingValue(null);}

注释1、2:做一个线程切换,切换到主线程中,并用线程安全的 synchronized()

注释3:确定当前线程是主线程,在非主线程中直接调用该方法会crash

注释4: 调用 dispatchingValue ,之后就是 considerNotify() 来通知观察者啦~

3.4 总结

  • LiveData 基于观察者模式实现和 LifecyclerOwner 绑定后能感知生命周期
  • 只有处于活跃状态的 Owne r才会接收到数据变化的通知,Owner从非活跃状态变为活跃状态,会接收到新的数据通知
  • Owner进入DESTROY状态会自动 remove Observer,不会担心内存泄露问题,如果希望一直接收到通知,可以使用 observeForever()方法
  • 主线程使用 setValue() 、工作线程使用 postValue() 进行数据更新

参考文章

《Android进阶指北》Android Jetpack架构组件
LiveData官方文档

http://www.jmfq.cn/news/5129983.html

相关文章:

  • 深圳网站定制 开发/朝阳seo搜索引擎
  • wordpress后台用户名/宁波抖音seo搜索优化软件
  • b2b行业网站建设/网络推广合作协议范本
  • 微网站矩阵怎么做/深圳网络推广哪家公司好
  • 创建一个个人网站需要多少钱/如何在百度上发广告
  • 如何做好网上销售/安卓aso关键词优化
  • 竞价推广培训/湖南seo优化推荐
  • 手机网站建设要素/移动端关键词排名优化
  • 仙桃做网站的个人/网站宣传文案范例
  • 查询网站建设/宁波seo基础入门
  • 设计师网站都有哪些/清远网站seo
  • 天津网站策划/安卓优化大师最新版
  • 求职网站建设/南宁seo渠道哪家好
  • 创建网站的过程/seo关键词优化排名外包
  • 代办公司是什么意思/四川网站seo
  • 北京建设职工大学网站/网络热词2022流行语及解释
  • wordpress网站漏洞/软文如何推广
  • 做网站底部不显示中文怎么回事/宣传推广渠道有哪些
  • 如何看出一个网站有做seo/南京百度搜索优化
  • 网站开发设计论文/宁波seo软件免费课程
  • 萝卜建站下载/免费sem工具
  • 多种郑州网站建设/seo网站排名优化服务
  • 十度公司做网站怎么样/网站提交链接入口
  • 网站开发项目培训/手游推广渠道
  • 做网站视频下载/搜索引擎营销案例分析
  • 网站建设自己在家接单/李江seo
  • 网站怎么做才被收录快/模板建站网页
  • 设计网站首页1/百度seo白皮书
  • 鹿邑网站建设/手机推广平台有哪些
  • 南京网站设计案例/管理培训