文章目录

    • 前言
    • 一,了解Jetpack
    • 二,Jetpack组件库介绍
    • 三,使用Jetpack架构开发模式
    • 四,Lifecycle源码分析
    • 五,LiveData源码分析
    • 六,ViewModel源码分析
    • 七,面试思维导图

前言

三种架构模式区别

MVC(Model-View-Controller)

MVC将应用抽象为数据层(Model)、视图(View)、逻辑(Controller) ,这样数据、视图、逻辑的代码各自汇聚。

MVC的目的就是将M和V的代码分离,且MVC是单向通信,必须通过Controller来承上启下。

问题:但是在MVC模式中,Model和View可能有耦合

MVP(Model-View-Presenter)

在MVC框架中,View层可以通过访问Model层来更新,但在MVP框架中,View层不能再直接访问Model层,必须通过Presenter层提供的接口,然后Presenter层再去访问Model层。各部分之间的通信是双向。

问题:Presenter的负担很重,Presenter需要知道View和Model的结构,并且在Model变化时候需要手动操作View,增加编码负担,降低代码维护性。

MVVM(Model-View-ViewModel)

MVVM设计了VM层,即ViewModel层,ViewModel自动同步数据到视图,用VM代替P之后,MVVM自动从Model映射到View(实现方式是模板渲染),不需要用户手动操作视图。

一,了解Jetpack

Jetpack是众多优秀组件的集合。是谷歌推出的一套引领Android开发者逐渐统一开发规范的架构。

Jetpack的优势

基于生命周期感知的能力,可以减少崩溃,,内存泄露,模板代码。为我们开发出健壮且高质量的程序提供保障。
组件可以单独使用,也可以搭配使用,搭配Kotlin语言特性可进一步加速开发。

二,Jetpack组件库介绍

1,Navigation

  • 特性:Activity,Fragment,Dialog提供路由能力的组件,导航时可携带参数,指定转场动画,支持deepline页面直达,fragment回退栈管理能力。
  • 不足:十分依赖xml文件,不利于模块化,组件化开发。

添加依赖

api "android.arch.navigation:navigation-fragment:2.0.0"api "android.arch.navigation:navigation-ui:2.0.0"

路由跳转,可携带参数,指定转场动画

NavController navController;navControll.navigate(int resId,Bundle args,NavOptions navOptions)

deepLink实现页面直达能力

navController.handleDeepLink("/detail/main")

管理Fragment回退栈

navController.popBackStack(int destinationId,boolean inclusive)

2,Lifecycle:具备宿主声明后期感知能力的组件

特性:它持有组件(如Activity或Fragment)生命周期状态的信息,并且允许其他对象观察此状态。

添加依赖

api "androidx.appcompat:appcompat:1.3.0"api "androidx.lifecycle:lifecycle-common:2.3.1"

Fragment源码,经典用法

public class Fragment implements xxx,LifecycleOwner{ LifecycleRegistry mLifecycleRegistry=new LifecycleRegistry(this); @Override public Lifecycle getLifecycle(){return mLifecycleRegistry; } class MyPresenter extends LifecycleObserver{@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)ovid onCreate(@NotNull LifecycleOwner owner){}@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)ovid onCreate(@NotNull LifecycleOwner owner){} }}getLifecycle().addObserver(mPresenter);//注册观察者,观察者宿主声明周期状态变化

3,ViewModel:具备生命周期感知能力的数据存储组件

特性:页面配置更改数据不丢失,生命周期感应,数据共享

api "androidx.appcompat:appcompat:1.3.0"api "androidx.lifecycle:lifecycle-viewmodel:2.3.1"api "androidx.lifecycle:lifecycle-livedata:2.3.1"

ViewModel的使用

class MyViewModel extends ViewModel {@Overrideprotected void onCleared() {super.onCleared();//宿主销毁时执行,可自我清理释放资源}MutableLiveData<ItemData> liveData = new MutableLiveData<>();public void getItemData(LifecycleOwner owner, Observer<ItemData> observer) {liveData.observe(owner, observer);liveData.setValue(itemData);}}

ViewModel数据共享

//构建ViewModel实力,需要使用ViewModelProvider来获取ViewModeld对象。//不同Fragment中获取同一个ViewModel实力,实现数据共享。class FragmentA extends Fragment {@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);MyViewModel myViewModel = new ViewModelProvider(getActivity().getViewModelStore(),new ViewModelProvider.NewInstanceFactory()).get(MyViewModel.class);}}

4,LiveData:具备生命周期感知能力的数据订阅,分发组件

  • 特性:支持共享资源,支持黏性事件的分发,不再需要手动处理生命周期,确保界面符合数据状态。
  • 不足:黏性事件不支持取消。
MutableLiveData<T> liveData=new MutableLiveData<T>()//注册一个跟宿主生命周期绑定的观察者,宿主销毁,会自动接触注册observe(LifecycleOwner owner, Observer<? super T> observer)//观察不到宿主生命周期,不会自动解除observeForever(Observer<? super observer>)//分发数据 只能用在主线程setValue(T value);//分发数据 子线程 主线程都可以使用postValue(T value)

5,Room:轻量级orm数据库,本质上是一个SQLite抽象层

特性:使用更加简单,通过注解的方式实现相关功能。编译时自动生成实现类impl

api "android.arch.persistence.room:runtime:1.1.1"kapt "android.arch.persistence.room:compiler:1.1.1"

Room使用

//创建操作数据库的实体层@Daopublic interface UserDao{ @Query("SELECT * FROM user") List<User> getAll(); @update("update table user set desc=:desc and where user_id = :userId") User updateUser(String desc,String userId); @Insert void insertAll(User...users); @Delete void delete(User user);}
//创建数据库@Database(entities={User.class,version=1})public abstract class MyDatabase extends RoomDatabase{public static MyDatabase myDatabase;static{myDatabase=Room.databaseBuilder(getApplicationContext(),AppDatabase.class,"database-name").build();}public abstract UserDao userDao();}//通过数据库单例对象,获取userDao数据操作对象myDatabase.userDao().getAll();

6,DataBinding:dataBinding只是一种工具,它解决的是View和数据之间的双向绑定。MVVM是一种架构模式

特性:数据与视图双向绑定,数据绑定空安全,减少模板代码,释放Activity/Fragment

使用DataBinding

android{ dataBinding{enabled=true }}

布局中绑定数据

<?xml version="1.0" encoding="utf-8"?><layout xmlns:android="http://schemas.android.com/apk/res/android"<data><variable name="user" type="com.test.app.model.User"/><import type="com.test.app.user.UserManager"></import></data><androidx.constraintlayout.widget.ConstraintLayout><TextView android:layout_width="200dp"//不能使用dataBinding动态绑定android:text="@{user.name}"//单向绑定数据变更自动通知UIandroid:testSize="@{dimen/16sp}"//资源引用android:text="@{user.name+@string/suffix}"//字符串的拼接需要引用资源android:test="@{UserManager.getUserName()}"//调用静态方法,类必须先导入android:onClick="@{()->UserManager.login()}"/><EditText//双向绑定数据变更自动更新UI,UI变更了也能自动更新user中的name数据android:text="@={user.name}"/></androidx.constraintlayout.widget.ConstraintLayout></layout>

7,WorkManager:新一代后台任务管理组件,功能十分丰富。service能做的事情它也能做。

支持周期性任务调度,链式任务调度,丰富的任务约束条件,即便程序退出,依旧能保证任务的执行

api "android.arch.work:work-runtime:1.0.1"

执行任务

//构建任务class UploadFileWorker extends Worker{ //执行文件上传 public Result doWork(){ return Result.success() }}//执行任务的request对象OneTimeWorkRequest request=new OneTimeWorkRequest.Builder(UploadFileWorker.class).build()//把任务加入调度队列WorkContinuation workContinuation=WorkManager.getInstance(context).beginWith(request)workContinuation.then(workB).then(workC).enqueue()

8,Paging:列表分页组件,可以轻松完成分页预加载已达到无限滑动的效果

特性:巧妙融合LiveData,提供多种数据源加载方式
不足:不支持列表数据增删改。列表添加HeaderView,FooterView定位不准确。

api “android.arch.paging:runtime:1.0.1”

//1 使用PagedList.Config对象,用以声明以何种方式分页PagedList.Config config=new PagedList.Config.Builder().setPageSize(10)//指定每次分页加载的条目数量.setInitialLoadSizeHint(12)//指定初始化数据加载的条目数量.build();//2 创建数据源工厂类,用来创建数据提供者DataSource.Factory factory=new DataSource.Factory(){ public DataSource create(){return new ItemKeyedDataSource(); }};//3 构建一个能够触发加载页面初始化数据的LiveData对象,并且把上面创建的DataSource.Factory和PagedListLiveData<PagedList<T>> pageData=new LivePagedListBuilder(factory,config).build();//4 拿到构建出来的LiveData对象注册一个Observer观察者,触发页面数据变化mViewModel.getPageData().observe(this,pagedList->submitList(pagedList));class MyItemKeyedDataSource extends ItemKeyedDataSource<GoodsModel>{public abstract void loadInitial省略....{//页面数据加载callback.onResult(list)}public abstract void loadAfter省略....{//向后分页数据加载callback.onResult(list)}public abstract void loadBefore省略....{//向前页面数据加载callback.onResult(list)}}

三,使用Jetpack架构开发模式

四,Lifecycle源码分析

1,Lifecycle的使用

使用1

//1.自定义的LifecycleObserver观察者,用注解声明每个方法观察的宿主状态//用注解的方式给方法添加对应的事件public class LocationObserverimplements LifecycleObserver{@OnLifecycleEvent(Lifecycle.Event.ON_START)void onStart(LifecycleOwner owner){//开启定位}@OnLifecycleEvent(Lifecycle.Event.ON_STOP)void onStop(LifecycleOwner owner){ //停止定位}}//2. 注册观察者 观察宿主生命周期状态变化public class LocationFragment extends Fragment{ @Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);LocationObserverobserver=new LocationObserver();getLifecycle().addObserver(observer); }}

使用2

public interface FullLifecycleObserver extends LifecycleObserver {void onCreate(LifecycleOwner owner);void onStart(LifecycleOwner owner);void onResume(LifecycleOwner owner);void onPause(LifecycleOwner owner);void onStop(LifecycleOwner owner);void onDestroy(LifecycleOwner owner);}class LocationObserver extends FullLifecycleObserver{void onStart(LifecycleOwner owner){}void onStop(LifecycleOwner owner){}}

使用3

public interface LifecycleEventObserver extends LifecycleObserver {/** * Called when a state transition event happens. * * @param source The source of the event * @param event The event */void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);}public class LocationObserver implements LifecycleEventObserver {@Overridepublic void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {//监听宿主生命周期状态}}

2,Lifecycle在Fragment源码中的实现

//Fragment源码中部分片段//Fragment实现了LifecycleOwner注册到LifecycleRegistry 在各个生命周期中调用handleLifecycleEventpublic class Fragment implements LifecycleOwner{LifecycleRegistry mLifecycleRegistry=new LifecycleRegistry(this);@NonNull@Overridepublic Lifecycle getLifecycle() {return mLifecycleRegistry;}void onCreate(){mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);}void performStart(){mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);}void performResume(){mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);}...}

Fragment源码中涉及到了三个类LifecycleOwner,Lifecycle,LifecycleRegistry,它们三者的关系如下图:
3,Lifecycle在ComponentActivity源码中的实现

//ComponentActivity 源码中部分片段public class ComponentActivity implements LifecycleOwner{LifecycleRegistry mLifecycleRegistry=new LifecycleRegistry(this);@NonNull@Overridepublic Lifecycle getLifecycle() {return mLifecycleRegistry;} protected void onCreate(Bundle bundle){super.onCreate(bundle);//往Activity上添加一个fragment,用以报告生命周期的变化//目的是为了兼顾不是继承自AppCompactActivity的场景ReportFragment.injectIfNeededIn(this);}}//ReportFragment 代码片段public class ReportFragment extends Fragment {private static final String REPORT_FRAGMENT_TAG = "androidx.lifecycle"+ ".LifecycleDispatcher.report_fragment_tag";public static void injectIfNeededIn(Activity activity) {// ProcessLifecycleOwner should always correctly work and some activities may not extend// FragmentActivity from support lib, so we use framework fragments for activitiesandroid.app.FragmentManager manager = activity.getFragmentManager();if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();// Hopefully, we are the first to make a transaction.manager.executePendingTransactions();}} @Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);dispatchCreate(mProcessListener);dispatch(Lifecycle.Event.ON_CREATE);}@Overridepublic void onStart() {super.onStart();dispatchStart(mProcessListener);dispatch(Lifecycle.Event.ON_START);}private void dispatch(Lifecycle.Event event) {Activity activity = getActivity();if (activity instanceof LifecycleRegistryOwner) {((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);return;}if (activity instanceof LifecycleOwner) {Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();if (lifecycle instanceof LifecycleRegistry) {((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);}}} }

从ComponentActivity 源码中可以看出LifecycleRegistry并没有在各个生命周期中去分发事件,而是通过ReportFragment 去实现,目的是为了兼顾不是继承自ComponentActivity 的场景。

如果继承了Activity自己实现了Lifecycle,这时会有个类LifecycleDispatcher,在此类DispatcherActivityCallback中又看到了ReportFragment的身影。

这就说明,如果没有继承ComponentActivity ,只要实现了LifecycleOwner接口,也能感知生命周期变化。

class LifecycleDispatcher {private static AtomicBoolean sInitialized = new AtomicBoolean(false);static void init(Context context) {if (sInitialized.getAndSet(true)) {return;}((Application) context.getApplicationContext()).registerActivityLifecycleCallbacks(new DispatcherActivityCallback());}@SuppressWarnings("WeakerAccess")@VisibleForTestingstatic class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {@Overridepublic void onActivityCreated(Activity activity, Bundle savedInstanceState) {ReportFragment.injectIfNeededIn(activity);}}}

4,LifecycleRegistry 源码分析

addObserver方法分析

 @Overridepublic void addObserver(@NonNull LifecycleObserver observer) {//注释1 State State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);if (previous != null) {return;}LifecycleOwner lifecycleOwner = mLifecycleOwner.get();if (lifecycleOwner == null) {// it is null we should be destroyed. Fallback quicklyreturn;}boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;State targetState = calculateTargetState(observer);mAddingObserverCounter++;//注释2 while 循环while ((statefulObserver.mState.compareTo(targetState) < 0&& mObserverMap.contains(observer))) {pushParentState(statefulObserver.mState);statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));popParentState();// mState / subling may have been changed recalculatetargetState = calculateTargetState(observer);}if (!isReentrance) {// we do sync only on the top level.sync();}mAddingObserverCounter--;}

注释1 State : 当前宿主的状态,并不是宿主的生命周期状态。两者的关系如下图:
对于两者的状态又是怎么通过代码实现的呢,我们主要来分析一下while中的代码。

注释2 while 循环
while用到的几个关键方法:

  • calculateTargetState():计算observer应该到达的状态,也就是当前宿主的状态。
  • upEvent():根据当前观察者的状态,判断应该接受哪个事件。
  • getStateAfter():根据分发的事件,判断当前观察者的状态。

while循环代码中的逻辑处理,是让观察者收到宿主完整的生命周期状态。例如:宿主在onResume生命周期注册一个observer,需要把宿主的onCreate,onStart,onResume都分发给observer。

再来看LifecycleRegistry 中的sync方法,用于同步生命周期状态。

 private void sync() {LifecycleOwner lifecycleOwner = mLifecycleOwner.get();if (lifecycleOwner == null) {throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"+ "garbage collected. It is too late to change lifecycle state.");}while (!isSynced()) {mNewEventOccurred = false;// no need to check eldest for nullability, because isSynced does it for us.if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {backwardPass(lifecycleOwner);}Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();if (!mNewEventOccurred && newest != null&& mState.compareTo(newest.getValue().mState) > 0) {forwardPass(lifecycleOwner);}}mNewEventOccurred = false;}

状态分发如何区分观察者类型,也就是如何区分LifecycleObserver ,FullLifecycleObserver ,LifecycleEventObserver 。

static class ObserverWithState {State mState;LifecycleEventObserver mLifecycleObserver;ObserverWithState(LifecycleObserver observer, State initialState) {mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);mState = initialState;}void dispatchEvent(LifecycleOwner owner, Event event) {State newState = getStateAfter(event);mState = min(mState, newState);mLifecycleObserver.onStateChanged(owner, event);mState = newState;}}

在Lifecycling类中的方法,在这里进行了类型的区分。

@NonNullstatic LifecycleEventObserver lifecycleEventObserver(Object object) {boolean isLifecycleEventObserver = object instanceof LifecycleEventObserver;boolean isFullLifecycleObserver = object instanceof FullLifecycleObserver;if (isLifecycleEventObserver && isFullLifecycleObserver) {return new FullLifecycleObserverAdapter((FullLifecycleObserver) object,(LifecycleEventObserver) object);}if (isFullLifecycleObserver) {return new FullLifecycleObserverAdapter((FullLifecycleObserver) object, null);}if (isLifecycleEventObserver) {return (LifecycleEventObserver) object;}final Class<?> klass = object.getClass();int type = getObserverConstructorType(klass);

五,LiveData源码分析

概念:LiveData组件是JetPack推出的基于观察者的消息订阅/分发组件,具有宿主(Activity,Fragment)生命周期感知能力,可以确保LiveData仅分发消息给处于活跃状态的观察者,即只有处于活跃状态的观察者才能收到消息。

1,基础介绍

LiveData简单使用

//1.注册观察者 liveData.observer(this,new Observer<User>{ void onChanged(User user){ } }) //2.发送消息 liveData.postValue(data);

MutableLiveData: 在使用LiveData做消息分发的时候,需要使用此类。只有拿到MutableLiveData对象才可以发送消息,LiveData对象只能接收消息,避免拿到LiveData对象既能发消息也能收消息。

public class MutableLiveData<T> extends LiveData<T> {public MutableLiveData(T value) {super(value);}public MutableLiveData() {super();}@Overridepublic void postValue(T value) {super.postValue(value);}@Overridepublic void setValue(T value) {super.setValue(value);}}

MediatorLiveData: 可以统一观察多个LiveData发射的数据进行统一处理,同时也可以做为一个liveData,被其他observer观察。

//创建两个LiveData对象LiveData<String> liveData1=new MutableLiveData();LiveData<String> liveData2=new MutableLiveData();//创建一个聚合类MediatorLiveDataMediatorLiveData<String> liveDataMerger=new MediatorLiveData<>();liveDataMerger.addSource(liveData1,observer);liveDataMerger.addSource(liveData2,observer);Observer observer=new Observer<String>(){@Overridepublic void onChanged(String string){}}

Transformations.map操作符: 可以对liveData进行变化,返回一个新的liveData对象。

MutableLiveData<Integer> liveData=new MutableLiveData();//数据转换LiveData<Integer> transformData=Transformations.map(data,input -> String.valueOf(input))//使用转换后的transformData去观察数据transformData.observe(this,output ->{});//发送数据liveData.setValue(10);

LiveData核心方法

方法名作用
observe(LifecycleOwner owner,Observer observer)注册和宿主生命周期关联的观察者
observeForever(Observer observer)注册观察者,不会反注册
setValue(T data)发送数据,没有活跃观察者时不分发。只能在主线程
postValue(T data)和setValue一样。但不受线程环境限制
onActive当且仅当有一个活跃的观察者时会触发
inActive不存在活跃的观察者时触发

2,LiveData消息分发原理

黏性消息分发流程

普通消息分发流程
LiveData源码中的observe方法:

@MainThreadpublic void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {assertMainThread("observe");if (owner.getLifecycle().getCurrentState() == DESTROYED) {// ignorereturn;}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);}

LifecycleBoundObserver源码,LifecycleBoundObserver实现了LifecycleEventObserver接口。在onStateChanged方法中,首先会判断当前宿主生命周期状态,如果是DESTROYED会移除当前消息。

class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {@NonNullfinal LifecycleOwner mOwner;LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {super(observer);mOwner = owner;}@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;activeStateChanged(shouldBeActive());currentState = mOwner.getLifecycle().getCurrentState();}}}

再看considerNotify方法中的mLastVersion 和mVersion。mLastVersion 和mVersion默认值都是-1。当调用setValue方法时mVersion会加1,这时mVersion就大于mLastVersion ,从而执行onChanged方法。

 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的改造

在源码中,我们知道在LiveData和Observer中有个version字段,当发送一条消息,和接收一条消息,通过version判断,以免消息重复发送。但是如果是黏性事件,先发送消息,后注册事件,那么就会有问题。

那么我们基于LiveData来实现一个不用反注册,且支持黏性事件的消息总线。

object HiDataBus {private val eventMap = ConcurrentHashMap<String, StickyLiveData<*>>()fun <T> with(eventName: String): StickyLiveData<T> {var liveData = eventMap[eventName]if (liveData == null) {liveData = StickyLiveData<T>(eventName)eventMap[eventName] = liveData}return liveData as StickyLiveData<T>}class StickyLiveData<T>(private val eventName: String) : LiveData<T>() {var mStickyData: T? = nullvar mVersion = 0fun setStickyData(stickyData: T) {mStickyData = stickyDatasetValue(stickyData)}fun postStickyData(stickyData: T) {mStickyData = stickyDatapostValue(stickyData)}override fun setValue(value: T) {mVersion++super.setValue(value)}override fun postValue(value: T) {mVersion++super.postValue(value)}override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {observerSticky(owner, false, observer)}private fun observerSticky(owner: LifecycleOwner,sticky: Boolean,observer: Observer<in T>) {owner.lifecycle.addObserver(LifecycleEventObserver { source, event ->if (event == Lifecycle.Event.ON_DESTROY) {eventMap.remove(eventName)}})super.observe(owner, StickyObserver(this, sticky, observer))}}class StickyObserver<T>(private val stickyLiveData: StickyLiveData<T>,private val sticky: Boolean,private val observer: Observer<in T>) : Observer<T> {private var lastVersion = stickyLiveData.mVersionoverride fun onChanged(t: T) {if (lastVersion >= stickyLiveData.mVersion) {if (sticky && stickyLiveData.mStickyData != null) {observer.onChanged(stickyLiveData.mStickyData)}return}lastVersion = stickyLiveData.mVersionobserver.onChanged(t)}}}

使用方法

 //发送消息 HiDataBus.with<String>("sticky").setStickyData("hello word") //接受消息sticky=true 可以接收黏性消息 HiDataBus.with<String>("sticky").observerSticky(this,true, Observer {Toast.makeText(this,it,Toast.LENGTH_LONG).show() })

六,ViewModel源码分析

概念:ViewModel具备宿主生命周期感知能力,保存数据在页面因配置变更导致页面销毁重建之后依然存在。

1,ViewModel的用法

常规用法: 存储数据,仅仅只能当页面因为配置变更导致的销毁再重建时可复用。复用的是ViewModel的实例对象整体。

class TestViewModel():ViewModel(){val liveData=MutableLiveData<List<GoodsModel>>()fun loadInitData():LiveData<List<GoodsModel>>{ if(liveData.value=null){val remoteData=fetchDataFromRemote()liveData.postValue(remoteData) } return liveData}}//通过ViewModelProvider来获取ViewModel对象val viewModel=ViewModelProvider(this).get(TestViewModel::class.java)viewModel.loadPageData().observer(this,Observer{ })

进阶用法: 存储的数据,无论是配置变更,还是内存不足,电量不足等系统原因导致页面被回收再重建,都可以复用。即便ViewModel不是同一个实例,它存储的数据也能做到复用。需要引入savedstate组件。

api 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0'
class TestViewModel(val savedState:SavedStateHandle):ViewModel(){ private val KEY_HOME_PAGE_DATA="key_home_page_data" private val liveData=MutableLiveData<List<GoodsModel>>() fun loadInitData():LiveData<List<GoodsModel>>{if(liveData.value=null){val memoryData=savedState.get<List<GoodsModel>>(KEY_HOME_PAGE_DATA)liveData.postValue(memoryData)return liveData}val remoteData=fetchDataFromRemote()savedState.set(KEY_HOME_PAGE_DATA,remoteData)liveData.postValue(remoteData) } return liveData}

跨页面数据共享

class MyApp:Application(),ViewModelStoreOwner{ private val appViewModelStore:ViewModelStore by lazy{ViewModelStore() } override fun getViewModelStore():ViewModelStore{ return appViewModelStore }}val viewmodel=ViewProvider(application).get(TestViewModel::class.java)

2,配置变更ViewModel复用原理

获取ViewModel实例

al viewModel=ViewModelProvider(this).get(TestViewModel::class.java)

在ViewModelProvider存在一个ViewModelStore 类用于存储ViewModel对象。

public ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory) {mFactory = factory;mViewModelStore = store;}

get方法获取当前实例,如果实例不存在ViewModelStore, 那么会通过Factory去创建实例。

 public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {ViewModel viewModel = mViewModelStore.get(key);if (modelClass.isInstance(viewModel)) {if (mFactory instanceof OnRequeryFactory) {((OnRequeryFactory) mFactory).onRequery(viewModel);}return (T) viewModel;} else {//noinspection StatementWithEmptyBodyif (viewModel != null) {// TODO: log a warning.}}if (mFactory instanceof KeyedFactory) {viewModel = ((KeyedFactory) mFactory).create(key, modelClass);} else {viewModel = mFactory.create(modelClass);}mViewModelStore.put(key, viewModel);return (T) viewModel;}

在ComponentActivity中获取ViewModelStore 对象

public ViewModelStore getViewModelStore() {if (getApplication() == null) {throw new IllegalStateException("Your activity is not yet attached to the "+ "Application instance. You can't request ViewModel before onCreate call.");}if (mViewModelStore == null) {NonConfigurationInstances nc =(NonConfigurationInstances) getLastNonConfigurationInstance();if (nc != null) {// Restore the ViewModelStore from NonConfigurationInstancesmViewModelStore = nc.viewModelStore;}if (mViewModelStore == null) {mViewModelStore = new ViewModelStore();}}return mViewModelStore;}

在ComponentActivity中存储ViewModelStore对象,这里就是关键,通过onRetainNonConfigurationInstance这个方法存储ViewModel对象,从而实现Activity配置变化后对ViewModel的复用。

public final Object onRetainNonConfigurationInstance() {Object custom = onRetainCustomNonConfigurationInstance();ViewModelStore viewModelStore = mViewModelStore;if (viewModelStore == null) {// No one called getViewModelStore(), so see if there was an existing// ViewModelStore from our last NonConfigurationInstanceNonConfigurationInstances nc =(NonConfigurationInstances) getLastNonConfigurationInstance();if (nc != null) {viewModelStore = nc.viewModelStore;}}if (viewModelStore == null && custom == null) {return null;}NonConfigurationInstances nci = new NonConfigurationInstances();nci.custom = custom;nci.viewModelStore = viewModelStore;return nci;}

ViewModel数据复用savedState组件

  • SavedStateHandle的数据存储与恢复。即便ViewModel不是同一个实例,它存储的数据也能做到复用。
  • SavedStateRegistryController:用于创建SavedStateRegistry。
  • SavedStateRegistry:数据存储和恢复。
  • SavedStateHandle:单个ViewModel数据存储和恢复。

SavedStateRegistry模型: 一个总Bundle,key-value存储着每个ViewModel对应字bundle
SavedState数据存储流程: 逐一调用每个SavedStateHandle保存自己的数据。汇总成一个总的Bundle,再存储到Activity的SavedState对象中。

SavedState数据复用流程(1): 从Activity的saveState恢复所有ViewModel数据到SavedStateRegistry
SavedState数据复用流程(2): 创建ViewModel并传递恢复的SavedStateHandle

Room搭配LiveData监听数据变更自动刷新页面实现原理

第一次向LiveData注册Observer时触发onActive,从而触发首次数据的懒加载。数据的加载在RefreshRunnable中完成,首次加载数据时会向InvalidationTracker注册监听表数据变更的observer,一旦表数据变更了,则会再次触发RefreshRunnable加载最新数据。

增删改三种操作开始之前会向一张表中写入本次操作的表的成名,并将状态置为1,操作完成后会触发InvalidationTracker.endTranstions。进而查询出所有数据变更了的表。然后回调给每一个RoomTracklingLiveData再次执行refreshRunnable重新加载数据,并发送到UI层的observer刷新页面。

七,面试思维导图

由于面试过程中往往不知道从何数起,这就需要把琐碎的知识点,汇总一下,理解着分步骤去记忆,这样更有条理,也方便复习。