2022年Android面试之Jetpack(AAC框架)篇
Posted 疯狂的皮卡
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2022年Android面试之Jetpack(AAC框架)篇相关的知识,希望对你有一定的参考价值。
文章目录
前言
谷歌官方推的Jetpack框架也已经有很长一段时间了,基本上新开的项目都会使用MVVM + kotlin + 协程的架构去搭建一些新的项目或者重构,因此面试中AAC框架在面试或多或少会提到,本篇主要是对几个常用框架进行高度概括,具体需要自行结合源码查阅
Lifecycle
- 功能:抽离Activity生命周期,提供API进行监听(观察者模式),使用状态模式保存了当前的状态以及前后两步的事件
- 注意点:非线程安全,在主线程调用
- 源码实现:在ComponentActivity会注入一个ReportFragment,里面会对生命周期进行分发(类似Glide)
- 注解(OnLifecycleEvent)使用原理:
- 2.4 之后已废弃,推荐设置监听的方式实现
- 实现LifecycleObserver接口,这个接口是个空接口,之后在需要的方法标记OnLifecycleEvent注解,例如
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
,然后调用Lifecycle#addObserver
方法,里面会构造一个ObserverWithState
,在ObserverWithState的构造函数会调用Lifecycling#lifecycleEventObserver
,通过注解反射获取到所有标注了的方法,在分发生命周期的时候会通过反射调用该方法- 通过
ObserverWithState
以及Lifecycling
统一了注解/继承 接口,以便调用;在其dispatchEvent
方法会获取
LiveData
- 功能:
- 具有观察生命周期能力的数据,本身观察Lifecycle,并且提供API作为被观察者监听数据变化(仅在生命周期有效时触发)
- 作为事件总线使用 —— LiveDataBus
源码分析
Observe 方法
- 首先根据调用的observe或者observeForever,对监听对象进行一次包装,然后添加到观察者集合,这里的包装是为了后续的统一操作(判断是否活跃等);一个监听对象只能对应一个lifecycle
- 接着如果是observeForever,会调用检查一次值状态进行分发(黏性);如果是observe方法,则会封装成LifecycleBoundObserver(实现了LifecycleEventObserver),并添加监听Livecycle的事件,后续会根据事件决定是否分发新值(活跃状态)
分发消息
- postValue(切换到主线程再调用setValue)
- setValue
无论是postValue还是 setValue,都会走到setValue,首先会更新LiveData的值,然后把版本号加一,再遍历所有观察者,判断生命周期并调用符合条件的观察者的onChange方法,注意这个遍历的过程,当所绑定的生命周期状态改变时也会进行一轮判断(ObserverWrapper#activiStateChange)
// mDispatchingValue: 是否正在分发值
// mDispatchInvalidated 是否分发完成
// 通过这两个状态控制分发状态 及时更新最新的值
void dispatchingValue(@Nullable ObserverWrapper initiator)
// 如果正在更新值 mDispatchInvalidated 直接置为true 这样下面do while会再执行一次 更新最新的值
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;
// 真正的把值传递出去
private void considerNotify(ObserverWrapper observer)
if (!observer.mActive)
return;
// 对观察者状态再次判断
if (!observer.shouldBeActive())
observer.activeStateChanged(false);
return;
// 避免重复调用
if (observer.mLastVersion >= mVersion)
return;
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
事件总线用法
- 可以将LiveData 以Map的形式存储起来,当做事件总线使用,但是有个问题是默认的消息是黏性的(数据倒灌)
- 解决方法:数据倒灌的原因是添加观察者的时候,此时会更新Lifecycle的状态,进一步同步值;此时可以通过反射修改Observer的Version值和LiveData的一样,这样就不会触发更新了
ViewModel
- 功能:在MVVM中的VM层,隔离View和Model,同时具有生命感知能力,能够在系统配置发生变更(旋转等)自动保存数据,同时提供clear方法在activity销毁的时候清除数据
- 保存复用:利用
ComponentActivity#onRetainNonConfigurationInstance
和ComponentActivity#getLastNonConfigurationInstance
,在activity消耗重建的时候重新赋值了一个ViewModelStore
,这个ViewModelStore实际上是一个存放ViewModel的Map(String-ViewModel),而在获取ViewModel的时候,也是在这个ViewModelStore去取,如果有则返回,没有的话则通过反射去创建一个并保存在这个Map中 - 销毁监听:在
ComponentActivity
创建时会注册一个LifecycleEvent监听,当收到 销毁事件且不是配置变更时 ,会调用ViewModelStore的clear方法,之后就是依次遍历调用clear的流程 ViewModelStore
的消耗:和onClear一样也是监听了lifecycleEvent,收到销毁事件清空
汇总图
常见面试题
MVP和MVVM优势和劣势
- MVP:从MVC中演化,进行解耦,和View层分离,减少Activity的负担;但是MVP会产生大量的接口和类文件;生命周期需要自己管理;View和P层耦合度较高,常常需要配合改动
- MVVM:M层完全关注于数据;更加的低耦合,VM不持有View相关,而且很多业务逻辑可以放在VM层复用;但是Databinding会导致XML文件难以复用并且难以Debug
- 最大的区别是在MVP中,P和V层是互相持有的,而在MVVM中,VM是不持有View,不再依赖View层,而是通过观察者模式观察数据变化(LiveData、DataBinding等)
ViewModel保存在Application和ViewModelScope的区别
生命周期的区别,一个是应用的生命周期一个是lifecycle的生命周期
ViewModel如何保证Activity销毁后保存数据
在Activity被销毁的时候,AMS会通过远程Binder调用
retainNonConfigurationInstances
方法,这个方法会调用onRetainNonConfigurationInstance
、getLastNonConfigurationInstance
保存一些配置,其中就包括ViewModelStore
,在重新创建Activity时,AMS会通过AMS#attach
将这个实例重新赋值
ViewModelProvider和ViewModelProviders
ViewModelProviders 是早期用于创建ViewModel的,新版本已经弃用,直接使用ViewModelProvider创建,对应的ViewModelStore也是由Activity/Fragment管理
ViewModel的保存和恢复
见上ViewModel篇
如何理解MVVM
- 首先MVVM是一种架构模式,在安卓开发中,谷歌为我们提供了一套jetpack框架用于快速实现MVVM(LiveData、Databinding、ViewModel),其中里面为我们处理了很多生命周期相关的重复性工作,消除了大量的重复代码
- AAC框架里面的核心我认为是Lifecycle,以Activity为例,是通过注入一个无UI的fragment,获取到生命周期的事件,再在里面维护了一个状态机,而且LiveData、ViewModel等的生命周期感知能力都是通过Lifecycle维护的这个状态去控制的
以上是关于2022年Android面试之Jetpack(AAC框架)篇的主要内容,如果未能解决你的问题,请参考以下文章
面试官:“会不会熟练使用Jetpack” 我:“......”
2022年Android面试题及答案汇总,每天20题持续更新中...(从面试官角度帮你审视问题)
2022年Android面试题及答案汇总,每天20题持续更新中...(从面试官角度帮你审视问题)
2022年Android面试题及答案汇总,每天20题持续更新中...(从面试官角度帮你审视问题)