今天一起来看看阿里面试真题LiveData的有关问题:
- LiveData 是什么?
- LiveData 为什么被设计出来,解决了什么问题?
- 说说LiveData原理。
LiveData 是什么?
LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。
官方介绍如下,其实说的比较清楚了,主要作用在两点:
数据存储器类
。也就是一个用来存储数据的类。可观察
。这个数据存储类是可以观察的,也就是比一般的数据存储类多了这么一个功能,对于数据的变动能进行响应。
主要思想就是用到了观察者模式
思想,让观察者和被观察者解耦,同时还能感知到数据的变化,所以一般被用到ViewModel中,ViewModel
负责触发数据的更新,更新会通知到LiveData
,然后LiveData再通知活跃状态的观察者。
var liveData = MutableLiveData<String>()
liveData.observe(this, object : Observer<String> {
override fun onChanged(t: String?) {
}
})
liveData.setVaile("xixi")
//子线程调用
liveData.postValue("test")
LiveData 为什么被设计出来,解决了什么问题?
LiveData
作为一种观察者模式设计思想,常常被和Rxjava
一起比较,观察者模式的最大好处就是事件发射的上游 和 接收事件的下游 互不干涉,大幅降低了互相持有的依赖关系所带来的强耦合性
。
其次,LiveData还能无缝衔接到MVVM
架构中,主要体现在其可以感知到Activity
等生命周期,这样就带来了很多好处:
- 不会发生内存泄漏 观察者会绑定到
Lifecycle
对象,并在其关联的生命周期遭到销毁后进行自我清理。 - 不会因 Activity 停止而导致崩溃 如果观察者的生命周期处于
非活跃状态
(如返回栈中的 Activity),则它不会接收任何 LiveData 事件。 - 自动判断生命周期并回调方法 如果观察者的生命周期处于
STARTED
或RESUMED
状态,则 LiveData 会认为该观察者处于活跃状态,就会调用onActive
方法,否则,如果 LiveData 对象没有任何活跃观察者时,会调用onInactive()
方法。
说说LiveData原理。
说到原理,其实就是两个方法:
- 订阅方法,也就是
observe
方法。通过该方法把订阅者和被观察者关联起来,形成观察者模式。
简单看看源码:
代码语言:javascript复制 @MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
//...
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);
}
public V putIfAbsent(@NonNull K key, @NonNull V v) {
Entry<K, V> entry = get(key);
if (entry != null) {
return entry.mValue;
}
put(key, v);
return null;
}
这里putIfAbsent
方法是讲生命周期相关的wrapper
和观察者observer
作为key和value存到了mObservers
中。
- 回调方法,也就是
onChanged
方法。通过改变存储值,来通知到观察者也就是调用onChanged
方法。从改变存储值方法setValue
看起:
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion ;
mData = value;
dispatchingValue(null);
}
private void dispatchingValue(@Nullable ObserverWrapper initiator) {
//...
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
for (Iterator<Map.Entry<Observer<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;
}
// 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);
}
这一套下来逻辑还是比较简单的,遍历刚才的map——mObservers
,然后找到观察者observer
,如果观察者不在活跃状态(活跃状态,也就是可见状态,处于 STARTED 或 RESUMED状态),则直接返回,不去通知。否则正常通知到观察者的onChanged方法。
当然,如果想任何时候都能监听到,都能获取回调,调用observeForever
方法即可。
总结
讲一下大厂面试一些必备的技能
1. 一般情况下第一轮都是基础面试,需要扎实的基础
- 最常用的Android 基础知识
- Java 基础知识
- 了解一些 常用东西的原理,例如:handler, thread 等
- 项目中的技术点
2. 第二轮的时候需要了解更深层次的东西
- Android 事件分发机制原理
- Android 绘图机制原理
- WindowManager 的相关知识
- 进程间传输方式
- Java 内存管理机制
3. 能进入第三轮基本没什么问题,但是要注意以下问题
- 该轮一般是 老大或者部门负责人,问的问题一般都看 深度与广度
- 当问及薪水的时候,要说一个合适的,小公司随意,大公司一定要慎重,当心里没底的时候,可以告诉对方,让对方给一个合理的薪资。一般都是在原工资基础之上增长,听猎头说一般涨幅都在15%-30%,超 NB 的可以要30%及以上,如果感觉自己还不错的,挺厉害的,建议最高20%,一般人就定在15% 左右最靠谱。公司内部一般有一套机制,根据公司情况而定。
- 我们的面试原则就是拿到合理薪资,得到 offer
- 个人发展情况,这个问题很难回答,如果和公司方向不符合,极有可能和公司无缘。建议多试探性的问问公司缺少什么,你能否给予公司对应的东西。当然对于有自我追求的人,那可以放心大胆的提。我的方向就是架构师,哈哈哈,挺极端的,别学我哦。我感觉选择都是双向的,因此我知道自己需要的是什么。
- 你最擅长什么UI 还是其他什么?这个问题更不好回答。你要说你擅长 UI,是不是意味着你其他能力就不行?虽然我不知道面试官的用意,但是我能感觉到,这个问题不是那么好回答,我会回答说自己都行,来什么业务接什么需求。可能回答不太好,总之和公司的职位吻合就行,这样总不至于出错吧。
那么该如何复习?
其实客户端开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。
这里再分享一下我面试期间的复习路线:(以下体系的复习资料是我从各路大佬收集整理好的)
《Android开发七大模块核心知识笔记》
最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2019-2020BAT 面试真题解析,我把大厂面试中常被问到的技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 诸多细节。
还有 高级架构技术进阶脑图 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
以上内容均放在了开源项目:【github】 中已收录,里面包含不同方向的自学Android路线、面试题集合/面经、及系列技术文章等,资源持续更新中...