Android|Android Jetpack架构组件Lifecycle+ViewModel+ LiveData

什么是Android Jetpack?

Android Jetpack是谷歌在2018年I/O开发者大会上推出的新一代组件、工具和架构指导,旨在加快开发者的 Android 应用开发速度。 ——官方介绍网站
Android Jetpack 组件是库的集合,这些库是为协同工作而构建的,不过也可以单独采用,同时利用 Kotlin 语言功能帮助您提高工作效率。可全部使用,也可混合搭配!
Android Jetpack组件的优势:
Jetpack推出的主要目的是为了能够让开发者更加快速、方便以及高质量的完成产品开发
  • 轻松管理应用程序的生命周期,后台任务的管理,导航的处理等等
  • 利用Jetpack组件进行开发可以有效减少内存溢出、崩溃的概率,提升应用开发的质量
Jetpack组件主要分为四个方向:基础,架构,行为和UI。详情见下
Android|Android Jetpack架构组件Lifecycle+ViewModel+ LiveData
文章图片
Android Jetpack组件推荐的使用项目架构
Android|Android Jetpack架构组件Lifecycle+ViewModel+ LiveData
文章图片
上面架构组件的功能如下:
  • Activity和Fragment负责产品与用户的交互
  • ViewModel作为数据的存储和驱动
  • Resposity负责调度数据的获取(Room储存本地序列化的数据,Retrofit获取远程数据的数据)
ViewModel+ LiveData ViewModel的优点:
  • 解决了运行中断和界面重建时的数据保存问题 (横竖屏切换,导致Activity销毁并重新创建时,ViewMode仍然可以保留之前读取到的数据不会因为Activity的销毁而丢失,这样我们无需额外再浪费资源去再次请求数据)
  • 配合LiveData实时获取最新数据
  • 实现Activity中Fragment之间的数据交互(数据共享)
  • 数据和界面的分离,使数据驱动界面 (ViewModel类被设计为通过lifecycle感知的方式存储和管理UI相关数据)
ViewModel的生命周期:
  • ViewModel对象的范围是在获取ViewModel时传递给ViewModelProvider的Lifecycle生命周期
  • ViewModel在内存中直到Activity销毁或Fragment被移除
  • 系统首次调用活动对象的onCreate()方法时,通常会请求ViewModel
  • 系统可能会在整个活动的整个生命周期中多次调用onCreate(),例如当设备屏幕旋转时
  • ViewModel从第一次请求ViewModel直到活动完成并销毁时存在
ViewMode在其生命周期的范围内会一直保存在内存中,所以横竖屏切换 当切换手机横竖屏后,Activity会destroy并重新onCreate来重构当前界面,生命周期再次重新触发onCreate,但是ViewMode 并没有重新执行获取数据的操作。
由于 ViewModel 生命周期可能长与 activity 生命周期,所以为了避免内存泄漏 Google 禁止在 ViewModel 中持有 Context 或 activity 或 view 的引用。
如果有些请求数据的情况必须用到Context,在继承ViewMode的时候,可以改为继承AndroidViewMode,这个类会返回一个带有Context的构造函数。
ViewMode执行onCleared操作,这个是ViewMode的一个回调,表明当前Activity要彻底关闭,ViewMode需要做一些回收清理的操作

Android|Android Jetpack架构组件Lifecycle+ViewModel+ LiveData
文章图片
LiveData 优点:
  • 确保UI界面的数据状态
  • 没有内存泄漏,不会因为Activity的不可见导致Crash
  • 一个存放可被观察的数据持有类,但与一般的被观察者不同的是,它是有生命周期感知功能,解决了android开发者需要去手动处理生命周期的痛点。
  • 共享资源
viewMode.getUserLiveData().observe(this, new Observer() { @Override public void onChanged(String users) { fragment2.setText("fragment2==\n" + users); } });

LiveData是一个observable数据持有类,LiveData是生命周期感知的,这意味着它跟随其他应用程序组件(如activities, fragments, or services)的生命周期。这种感知能力确保LiveData只更新处于活跃生命周期状态的应用程序组件
LiveData与一个Observer关联,如果观察者的生命周期处于STARTED或RESUMED状态,则表示观察者处于活动状态。LiveData只通知活跃的观察者做更新。注册到LiveData对象中的不活跃的观察者则得不到数据更新的通知。
注册一个observer并与实现了LifecycleOwner接口的对象配对。这种关系允许当相应的Lifecycle对象的状态改变为DESTROYED时,观察者被移除
利用ViewMode(配合LiveData实时获取最新数据)进行Fragment之间的数据交互
public class OneFragment extends BaseFragment { @BindView(R2.id.fragment2) TextView fragment2; @Override protected int initLayout() { return R.layout.fragment_detail; } @Override protected void initView(View view) { //绑定ViewMode的selected的值,当有更新时通知DetailFragment SharedViewModel viewMode = ViewModelProviders.of(getActivity()).get(SharedViewModel.class); viewMode.getUserLiveData().observe(this, new Observer() { @Override public void onChanged(String users) { fragment2.setText("fragment2==\n" + users); } }); }}public class TwoFragment extends BaseFragment { @BindView(R2.id.fragment1) TextView fragment1; SharedViewModel viewMode; @Override protected void initView(View view) { //注意:这里ViewModelProviders.of(getActivity())这里的参数需要是Activity,而不能是Fragment,否则收不到监听 viewMode = ViewModelProviders.of(getActivity()).get(SharedViewModel.class); fragment1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //当点击某一个item的时候,更新viewmode中的selected的值 viewMode.select("fragment1点击后,更新viewmode中的值,fragment2 里面的数据同步更新"); } }); }@Override protected void initData() { viewMode.getUserLiveData().observe(this, new Observer() { @Override public void onChanged(String users) { Log.w("TAG", "====" + users); } }); }@Override protected int initLayout() { return R.layout.fragment_master; } }public class SharedViewModel extends AndroidViewModel { //userLiveData保存的是被选中的item的状态或者数据 private MutableLiveData userLiveData; public MutableLiveData getUserLiveData() { if (userLiveData =https://www.it610.com/article/= null) { Log.w("TAG", "SharedViewModel-getUserLiveData"); userLiveData = https://www.it610.com/article/new MutableLiveData<>(); } return userLiveData; }//主要通过masterFragment进行调用交互,用来更新selected中的值 public void select(String item) { userLiveData.setValue(item); }public SharedViewModel(@NonNull Application application) { super(application); }/** * 这里可以执行一些资源释放、数据清理的操作 * ViewMode会执行onCleared操作,这个是ViewMode的一个回调, * 表明当前Activity要彻底关闭,ViewMode需要做一些回收清理的操作,如下代码: */ @Override protected void onCleared() { super.onCleared(); } }

上述代码的逻辑很简单,OneFragment与TwoFragment并不直接进行交互,而是各自与ViewMode进行交互,OneFragment用来更新维护ViewMode中的数据,TwoFragment可以收到来自ViewMode中数据更新的通知。这样便达到了两个frangment之间的数据通信。
LifeCycles原理 Lifecycles是生命周期管理组件 另一组件的生命周期状态(随着Activity和Fragment)的变化而执行动作,support 26 以上的兼容包中的AppCompatActivity与Fragment中默认已实现了LifeCycleOwner接口,保证了LiveData及ViewModel具备了生命周期感知与内存缓存的能力。
场景使用:在平时的开发过程中,我们难免有些逻辑的执行是和UI的生命周期相结合的,需要在特定的生命周期中执行相应的方法,我们平时做的可能就是在View中的每个周期调用Present中获取数据的方法,然后在调用View的回调接口更新UI,但现在使用Lifecycles可以使用注解和观察的模式自动调用Observe中定义好的方法。
//谁观察生命周期就注册谁两个角色定义好后,需要让他们之间建立联系 //获取Lifecycle getLifecycle().addObserver(new LocationListener()); public class LocationListener implements LifecycleObserver { private static final String TAG = "TAG"; @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) public void onActivityCreate(LifecycleOwner owner) { Log.w(TAG, "onActivityCreate"); }@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) public void onActivityDestroy(LifecycleOwner owner) { Log.w(TAG, "onActivityDestroy"); }@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) public void onActivityPause(LifecycleOwner owner) { Log.w(TAG, "onActivityPause"); }@OnLifecycleEvent(Lifecycle.Event.ON_RESUME) public void onActivityResume(LifecycleOwner owner) { Log.w(TAG, "onActivityResume"); }@OnLifecycleEvent(Lifecycle.Event.ON_START) public void onActivityStart(LifecycleOwner owner) { Log.w(TAG, "onActivityStart"); }@OnLifecycleEvent(Lifecycle.Event.ON_STOP) public void onActivityStop(LifecycleOwner owner) { Log.w(TAG, "onActivityStop"); }}

Lifecycle 原理 如何感知 activity 或 fragment 生命周期 1、activity 和 fragment 已经实现了 LifecycleOwner
2、出现了一个LifecycleRegistry,是 Lifecycle 的一个实现类。通过markState方法在onSaveInstanceState把 Lifecycle 状态标记为Lifecycle.State.CREATED。
3、onCreate 方法里有个ReportFragment,
4、利用 fragment 的特性,绑定了一个 fragment 然后在其生命周期dispatch()方法中调用了LifecycleRegistry的handleLifecycleEvent,此方法便是通知观察者的地方。Lifecycle.Event,判断执行事件后下一个到达的状态,然后使用moveToState()中修改活动的生命周期
5、通知观察者addObserver 后,把observer维护到ObserverWithState然后装到 map 里。
然后通过handleLifecycleEvent方法最终遍历map 通知 observer。
伪代码 public class ComponentActivity extends androidx.core.app.ComponentActivity implements LifecycleOwner{ private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this); @CallSuper @Override protected void onSaveInstanceState(@NonNull Bundle outState) { mLifecycleRegistry.markState(Lifecycle.State.CREATED); super.onSaveInstanceState(outState); } @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); mSavedStateRegistryController.performRestore(savedInstanceState); ReportFragment.injectIfNeededIn(this); if (mContentLayoutId != 0) { setContentView(mContentLayoutId); } }public void addObserver(@NonNull LifecycleObserver observer) { State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED; ObserverWithState statefulObserver = new ObserverWithState(observer, initialState); ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver); }

ViewModel 原理
getLifecycle().addObserver(new LifecycleEventObserver() { @Override public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) { if (event == Lifecycle.Event.ON_DESTROY) { if (!isChangingConfigurations()) { getViewModelStore().clear(); } } } });

ViewModel 和 onSaveInstaceState方法区别在于:ViewModel只能保存因为配置更改导致重建的数据,但是它能保存大量和复杂的数据;onSaveInstaceState能保存配置更改导致重建和资源限制导致重建的数据,但是它只能保存少量简单的数据。ViewModel使用SavedStateHandle能够保存资源限制导致重建的数据。
根据传入的Activity获取、创建、添加并以键值对保存Fragment,从VIewStore的Map中或Factory的create()中获取ViewMode
1、获取ViewProvider:
2、获取ViewModelStore:由前面的源码可以知道创建ViewProvider时传入两个参数:ViewModelStore 和 Factory;显然从名字就可以看出他们的作用,Factory负责创建,ViewModelStore负责存储
ViewModelStore内部维护者一个Map集合保存者ViewModel对象的键值对
ViewModel的生命周期要比Activity长一点。因为在ComponentActivity 实现了的getViewModelStore ,ViewModelStore在Activity重建前后能保持同一个对象就是通过NonConfigurationInstances实现的。
ActivityThread 里面performLaunchActivity方法里面,启动Activity 调用了Activity的attach方法,在这个方法,将已有的NonConfigurationInstances赋值给了新的Activity对象。所以Activity 获取到的ViewMode是同一个,
这样NonConfigurationInstances能保证ViewModelStore在Activity重建前后是同一个对象,同时也知道为啥ViewModel的生命周期比Activity的生命周期要长一点
LiveData 原理,如何做到生命周期感知: 涉及到LifecycleOwner属于另一个架构组件 lifecycle,lifecycle原理上面已经讲述
伪代码 //LiveData数据可以再通过observe方法进行数据回调的返回,如上代码中的onChanged回调。 //从Livedata添加观察者的方法 observe 开始: viewMode.getUsers().observe(this, new Observer() { @Override public void onChanged(String users) { viewmode_text.setText("viewMode获取到的数据--" + users); } }); public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) { assertMainThread("observe"); if (owner.getLifecycle().getCurrentState() == DESTROYED) { // ignore return; } 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); }

第一个参数为LifecycleOwner用于提供当前的生命周期状态,DESTROYED的时候不做任何操作。
第二个为观察者observer,首先把observer包装成了LifecycleBoundObserver,然后把LifecycleBoundObserver维护到mObservers里
private SafeIterableMap, ObserverWrapper> mObservers = new SafeIterableMap<>();
mObservers是一个LinkedList结构的容器 通过putIfAbsent方法判断,容器中此观察者是不是已经存在,如果存在且LifecycleOwner不同的话则抛异常,LifecycleOwner相同则 return 不重复添加。
LifecycleBoundObserver实现了LifecycleObserver,为lifecycle 的观察者,通过上文的 observe方法添加到了lifecycle观察中,
接下来主要看LifecycleBoundObserver
通过此类持有 Livedata 的观察者observer,当 生命周期发生变化时 会回调onStateChanged方法,然后 Livedata 的观察者在onStateChanged中执行相应的逻辑。
@Override public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) { if (mOwner.getLifecycle().getCurrentState() == DESTROYED) { removeObserver(mObserver); return; } activeStateChanged(shouldBeActive()); } //接着执行activeStateChanged void activeStateChanged(boolean newActive) { if (newActive == mActive) { return; } // immediately set active state, so we'd never dispatch anything to inactive // owner mActive = newActive; boolean wasInactive = LiveData.this.mActiveCount == 0; LiveData.this.mActiveCount += mActive ? 1 : -1; if (wasInactive && mActive) { onActive(); } if (LiveData.this.mActiveCount == 0 && !mActive) { onInactive(); } if (mActive) { dispatchingValue(this); } }

【Android|Android Jetpack架构组件Lifecycle+ViewModel+ LiveData】通过巧妙的设计实现了:
1、状态没有变化,什么也不做。
2、变为活(active)就是调用onActive(),非活(inactive)就调用onInactive().
3、另外,变为活的话就调用dispatchingValue方法,此方法为回调观察者的方法
事件的通知
LiveData通过 setValue 或 postValue 方法去改变持有的数据,并通知观察者,最终都是调用dispatchingValue()方法:
void dispatchingValue(@Nullable ObserverWrapper initiator) { ........................................ //遍历之前注册的观察者 for (Iterator, ObserverWrapper>> iterator = mObservers.iteratorWithAdditions(); iterator.hasNext(); ) { considerNotify(iterator.next().getValue()); if (mDispatchInvalidated) { break; } } } } while (mDispatchInvalidated); mDispatchingValue = https://www.it610.com/article/false; } private void considerNotify(ObserverWrapper observer) { ................................ if (observer.mLastVersion>= mVersion) { return; } observer.mLastVersion = mVersion; //开始通知了 observer.mObserver.onChanged((T) mData); }

    推荐阅读