时间:2021-05-21
前言
前面两篇文章我们已经学习了Lifecycle和DataBind,本篇文章我们来学习Jetpack系列中比较重要的ViewModel,Jetpack的很多很多组件都是搭配使用的,所以单独的知识点可能会有些”无意义“但却是我们项目实战的基础!
ViewModel的使用
ViewModel类旨在以注重生命周期的方式存储和管理界面相关的数据。ViewModel类让数据可在发生屏幕旋转等配置更改后继续存在。这句话很好理解,还记得我们在讲解Lifecycle的时候 举的例子吗,我们还是使用那个例子,如果你还没看过,可移步至:
Android Jetpack系列之Lifecycle
我们再回顾一次需求:
在Activity 可见的时候,我们去做一个计数功能,每隔一秒 将计数加1 ,当Activity不可见的时候停止计数,当Activity被销毁的时候 将计数置为0,这里我们在Activity被销毁的时候不再将count置为0,WorkUtil代码如下所示:
public class WorkUtil implements LifecycleObserver { private static final String TAG = "WorkUtil"; private boolean whetherToCount = true; private int count = 0; @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) public void start() { new Thread(new Runnable() { @Override public void run() { while (whetherToCount) { try { Thread.sleep(1000); count++; Log.d(TAG, "start: " + count); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) public void onStop() { whetherToCount = false; Log.d(TAG, "onStop: "); } @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) public void onDestory() { }}我们运行程序,在计数的过程中 使屏幕旋转,运行结果如下所示:
我们可以看到,当屏幕旋转的时候,由于生命周期发生了改变,导致数据被销毁,所以计数器的计数又从初始值开始计数了,那么我们如何解决这个问题呢,你肯定会说,缓存呀,重写onSabeInstanceState()方法等等,都可以但是都不够优雅,那么如何优雅的来解决这个问题呢,这就是我们的今天的主角ViewModel。
ViewModel的使用
我们新建Main3ActivityModel 继承自 ViewModel,在Main3ActivityModel中定义count变量 如下所示:
public class Main3ActivityViewModel extends ViewModel { public int count = 0; }没错,就是这么简单,我们只要保证计数的变量是这个model中的变量,就可以解决我们上面的问题
我们通过ViewModelProviders来获取ViewModel对象
main3ActivityViewModel = ViewModelProviders.of(this).get(Main3ActivityViewModel.class);
但是这个方法已经过时了,替代方法是
main3ActivityViewModel = new ViewModelProvider(this).get(Main3ActivityViewModel.class);
为了让WorkUtil使用Model中的变量,所以我们要将ViewModel 传递过去,在WorkUtil中新增一个构造方法
private Main3ActivityViewModel main3ActivityViewModel; public WorkUtil(Main3ActivityViewModel main3ActivityViewModel) { this.main3ActivityViewModel = main3ActivityViewModel;}我们将WorkUtil中的计数变量count 改为 main3ActivityViewModel.count,如下所示:
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)public void start() { new Thread(new Runnable() { @Override public void run() { while (whetherToCount) { try { Thread.sleep(1000); main3ActivityViewModel.count++; Log.d(TAG, "start: " + main3ActivityViewModel.count); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start();}main3Activity中在lifecycle中传参:
getLifecycle().addObserver(new WorkUtil(main3ActivityViewModel));
再次运行程序,运行过程中旋转手机屏幕,打印如下所示:
我们可以看到,在屏幕旋转之后,计数器的计数保留了,那么viewModel是如何做到的呢,这是因为ViewModel 对象存在的时间比视图或 LifecycleOwners 的特定实例存在的时间更长,ViewModel的生命周期如下图所示(摘自官网)
向ViewModel传参
当前计数的需求是从0开始计时,我们现在修改需求如下,使用用户输入的数字为起点开始计数,这样的话ViewModel中的count就不是0了,而是传入的参数,我们在Main3Activity中定义变量inputCount 来模拟用户输入的数字
private int inputCount = 100;
在Main3ViewModel中添加构造方法
public int count = 0; public Main3ActivityViewModel(int count) { this.count = count;}看到这里,你可能会说,我们直接new一个传过去不就行了吗,请记住这是万万不行的,因为如果我们使用直接实例化来创建ViewModel,那么ViewModel的生命周期就受Activity的影响了,所以为什么我们只能通过ViewModelProvider来获取ViewModel的实例。
我们需要借助ViewModelProvider.Factory来实现传参,新建Main3ActivityViewModelFactor继承自 ViewModelProvider.Factory,重写其onCreate方法,如下所示:
public class Main3ActivityViewModelFactory implements ViewModelProvider.Factory { @NonNull @Override public <T extends ViewModel> T create(@NonNull Class<T> modelClass) { return null; }}添加一个构造方法,并在create中创建VideModel实例
private int count; public Main3ActivityViewModelFactory(int count) { this.count = count;} @NonNull@Overridepublic <T extends ViewModel> T create(@NonNull Class<T> modelClass) { return (T) new Main3ActivityViewModel(count);}在Activity中获取实例的时候 采用如下方法
main3ActivityViewModel = new ViewModelProvider(this,new Main3ActivityViewModelFactory(inputCount)).get(Main3ActivityViewModel.class);
运行程序,打印结果如下所示:
如此一来 我们就实现ViewModel传递参数了~
以上就是Android Jetpack架构组件 ViewModel详解的详细内容,更多关于Android Jetpack架构组件 ViewModel的资料请关注其它相关文章!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
Google推出Jetpack组件化已经有相当一段时间了。各种组件也层出不穷。Jetpack的东西也不少,今天就搞一下这个PagingPaging的出现,就是用
SupportLibrary26.1+直接支持生命周期架构组件。使用该组件,Android生命周期的梦魇已经成为过去。再也不用担心出现Cannotperform
在GoogleI/O2018开发者大会上,谷歌官方推出了AndroidJetpack,其中包含的Android开发架构组件能够帮助我们简化开发流程,从而轻松打造
本节引言告别了章,迎来第二章——Android中的UI(UserInterface)组件的详解,而本节我们要学习的是所有控件的父类View和ViewGroup类
Vue.js是当下很火的一个JavaScriptMVVM(Model-View-ViewModel)库,它是以数据驱动和组件化的思想构建的。相比于Angular