最全Jetpack学习之 LiveData,2024年最新2024山东选调面试题目

最后看一下学习需要的所有知识点的思维导图。在刚刚那份学习笔记里包含了下面知识点所有内容!文章里已经展示了部分!如果你正愁这块不知道如何学习或者想提升学习这块知识的学习效率,那么这份学习笔记绝对是你的秘密武器!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

确保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()

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()

// 1

liveDataSwitch = MutableLiveData()

// 如果是true,选择监听1,否则监听2

val 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()

val mutableLiveData2 = MutableLiveData()

// 创建一个用于合并数据源的LiveData

val liveDataManager = MediatorLiveData()

// 添加数据 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() {

companion object {

private const val TAG = “ExtStringLiveData”

private var sInstance: ExtStringLiveData? = null

@MainThread

fun 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 的同学肯定就知道了其中的奥秘。我们来看看它的源码吧:

@MainThread

public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {

assertMainThread(“observe”);

// 1

if (owner.getLifecycle().getCurrentState() == DESTROYED) {

return;

}

// 2

LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);

// 3

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;

}

// 4

owner.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;

@Override

boolean shouldBeActive() {

return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);

}

@Override

public 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;

// 1

activeStateChanged(shouldBeActive());

currentState = mOwner.getLifecycle().getCurrentState();

}

}

@Override

boolean isAttachedTo(LifecycleOwner owner) {

return mOwner == owner;

}

@Override

void 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) {

// 1

dispatchingValue(this);

}

}

}

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

其次,如果当前是 Active 状态,则调用注释1的 dispatchingValue() 方法

void dispatchingValue(@Nullable ObserverWrapper initiator) {

// 如果当前正在分发, 则返回

if (mDispatchingValue) {

// 表示分发无效

mDispatchInvalidated = true;

架构师筑基包括哪些内容

我花了将近半个月时间将:深入 Java 泛型.、注解深入浅出、并发编程.、数据传输与序列化、Java 虚拟机原理、反射与类加载、高效 IO、Kotlin项目实战等等Android架构师筑基必备技能整合成了一套系统知识笔记PDF,相信看完这份文档,你将会对这些Android架构师筑基必备技能有着更深入、更系统的理解。

由于文档内容过多,为了避免影响到大家的阅读体验,在此只以截图展示部分内容

注:资料与上面思维导图一起看会更容易学习哦!每个点每个细节分支,都有对应的目录内容与知识点!



这份资料就包含了所有Android初级架构师所需的所有知识!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

哪些内容

我花了将近半个月时间将:深入 Java 泛型.、注解深入浅出、并发编程.、数据传输与序列化、Java 虚拟机原理、反射与类加载、高效 IO、Kotlin项目实战等等Android架构师筑基必备技能整合成了一套系统知识笔记PDF,相信看完这份文档,你将会对这些Android架构师筑基必备技能有着更深入、更系统的理解。

由于文档内容过多,为了避免影响到大家的阅读体验,在此只以截图展示部分内容

注:资料与上面思维导图一起看会更容易学习哦!每个点每个细节分支,都有对应的目录内容与知识点!

[外链图片转存中…(img-LvumdOPI-1715412116623)]
[外链图片转存中…(img-M1CyqdU7-1715412116623)]
这份资料就包含了所有Android初级架构师所需的所有知识!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 12
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值