ViewModel是一种用于管理UI相关数据的架构组件,它能够帮助开发者实现优雅的数据驱动和生命周期管理。本文将深入浅出地介绍ViewModel的使用和原理,带你一步步掌握这个强大的组件。...什么是ViewModel ViewModel是Android Jetpack组件之一,它的主要目的是将UI控制器(如Activity和Fragment)与数据相关的业务逻辑分开,使得UI控制器能够专注于展示数据和响应用户交互...,而数据的获取和处理则交由ViewModel来管理。...这样,UI控制器可以在重建后重新获取之前的ViewModel实例,并继续使用其中的数据,从而避免数据丢失和重复加载。...ViewModel的出现极大地简化了Android开发中的数据管理和生命周期处理,使得应用更加健壮和高效。在实际开发中,合理使用ViewModel能够帮助你构建优雅、易维护的Android应用。
引言 在Android开发中,数据的管理是一个至关重要的问题。随着应用复杂度的增加,我们需要一种能够有效管理数据和处理UI相关逻辑的机制。Android架构组件中的ViewModel应运而生。...通过使用ViewModelStore,这些组件可以共享同一个ViewModel实例,避免了数据的重复加载和同步问题。...高级运用 使用SavedStateHandle SavedStateHandle是一个可用于在配置更改后保持数据的工具。它允许我们将数据与ViewModel关联,以便在应用重新创建时检索。...{ return savedStateHandle.get(dataKey) } } 处理异步操作 ViewModel可以与协程结合,以处理异步操作。...将ViewModel的职责限制在处理UI相关的逻辑,不要包含过多的业务逻辑。 谨慎使用SavedStateHandle,避免将大量数据存储在其中导致性能问题。
把从网络获取的图片数据保存在SD卡上, 先把权限都加上 网络权限 android.permission.INTERNET SD卡读写权限 android.permission.MOUNT_UNMOUNT_FILESYSTEMS...),获取联系人的,getImages()获取图片 开启新线程,使用ContactService.getContacts()里面实现获取网络数据,返回List对象,使用Handler传递数据给主线程 创建缓存图片的...()方法,判断目录是否存在,不存在就创建,调用File对象的mkdirs() 展示ListView 设置ContactsAdapter类的构造函数,传递进去参数:数据,布局文件,缓存目录FIle对象...重写getCount()方法,return数据的条数 重写getItem()方法,返回 根据索引得到的集合中的数据,List对象的get()方法,参数:索引 重写getItemId()方法,一般返回数据的索引...如果直接加载容易anr,所以要异步加载图片 异步加载并保存图片 开启线程执行加载图片的代码 在ContactService业务类里实现getImage()方法,通过get方式读取图片,得到Uri对象,参数
—— ViewModel 与导航 (Navigation) 组件库的集成; ViewModel 配合数据绑定(data-binding) —— 通过使用 ViewModel 和 LiveData 简化数据绑定...所以一旦出现了第三种情况,便需要在 Activity 的 onSaveInstanceState 相关回调中保存和恢复 ViewModel 中的数据。...在免除了与 Activity 繁琐的数据交换后,ViewModel 也真正意义上的做到了管理和持有所有自己的数据。 ViewModel 的这一新功能是通过 SavedStateHandle 实现的。...SavedStateHandle 和 Bundle 一样,以键值对形式存储数据,它包含在 ViewModel 中,并且可以在应用处于后台时进程被杀死的情况下幸存下来。...每当数据更新时,要保存新的数据到 SavedStateHandle; 获取: 如代码中所示,调用 savedStateHandle.get(USER_KEY) 方法获取被保存的 userId。
ViewModel 可以将数据层与 UI 分离,而这种架构不仅可以简化 UI 的生命周期的控制,也能让代码获得更好的可测试性。如果想了解更多,可以参考 ViewModel: 简单介绍视频和官方文档。...—— ViewModel 与导航 (Navigation) 组件库的集成; ViewModel 配合数据绑定(data-binding) —— 通过使用 ViewModel 和 LiveData 简化数据绑定...在免除了与 Activity 繁琐的数据交换后,ViewModel 也真正意义上的做到了管理和持有所有自己的数据。 ViewModel 的这一新功能是通过 SavedStateHandle 实现的。...SavedStateHandle 和 Bundle 一样,以键值对形式存储数据,它包含在 ViewModel 中,并且可以在应用处于后台时进程被杀死的情况下幸存下来。...每当数据更新时,要保存新的数据到 SavedStateHandle; 获取: 如代码中所示,调用 savedStateHandle.get(USER_KEY) 方法获取被保存的 userId。
上篇文章提到,虽然viewModel要比onSaveInstanceState简单,但是viewModel只能在屏幕旋转和语言切换后(即配置变更时)的页面重建维持数据,当页面意外销毁时数据无法恢复(viewModel...可见当页面意外销毁时,viewModel并不能很好的维持数据。...解决 如果需要让ViewModel能在页面意外销毁时维持数据,那就需要结合SavedStateHandle使用了,新建一个ViewModel, class SavedStateViewModel extends...发现虽然mSavedStateViewModel不再是同一个实例,但是数据是可以恢复的。...不再是同一个实例,但是数据都被恢复过来了 return new SavedStateHandle(state); } 即本质还是通过Bundle的序列化和反序列化来恢复数据的。
导航 学完本篇,你将了解或明白以下内容: ViewModel 的使用方式; SavedStateHandle 的使用方式; ViewModel 创建与销毁流程; SavedStateHandle 创建流程...ViewModel存在之前的世界 在 ViewModel 出现之前,对于 View 逻辑与数据,我们往往都是直接存在 Activity 或者 Fragment 中,优雅一点,会细分到具体的单独类中去承载...相应的,我们的数据在没有额外处理的情况下,往往也会被初始化,然后在界面重启时重新加载。 但如果当前页面需要维护某些状态不被丢失呢,比如 选择、上传状态 等等? 此时问题就变得棘手起来。...所以,在现在的开发中,我们开始将 View数据 与 逻辑 藏于 ViewModel 中,然后对外部暴漏观察者,比如我们常常会搭配 LiveData 一起使用,以此更容易的保持状态同步。...在具体的创建方法中,需要判断当前构造函数是不是带 application 或者 SaveStateHandle ,从而调用合适的 newInstance() 方法,最后再将创建好的 ViewModel
我们的需求就是在不添加回调函数的情况下,把异步获取的数据加载出来。 源码 点击这里前往Github查看本文源码。...问题抽象 这里用setTimeout代替一个异步网络请求: let data function setDataAsync() { setTimeout(() => { data...}, 1000) } setDataAsync() console.log(data) // undefined 显然,这里还没等data拿到就执行了console.log,导致我们获取到的是
iOS开发之swift版异步加载网络图片 与SDWebImage异步加载网络图片的功能相似,只是代码比较简单,功能没有SD的完善与强大,支持缺省添加图片,支持本地缓存。 ...异步加载图片的核心代码如下: func setZYHWebImage(url:NSString?, defaultImage:NSString?...self.image=ZYHImage }else{ //获取异步线程 var dispath=dispatch_get_global_queue...ZYHImage }) } }) } } } 缓存的处理这里采用的是写文件的方式...缓存的核心代码如下: class func readCacheFromUrl(url:NSString)->NSData?{ var data:NSData?
大家好,我是稳稳,一个曾经励志用技术改变世界,现在为随时失业做准备的中年奶爸程序员,与你分享生活和学习的点滴。 连续熬夜真是吃不消啊!加油!加油! 引言:为什么开发者需要ViewModel?...而ViewModel的诞生,通过“生命周期穿透”能力,彻底解决了配置变更导致的数据丢失问题。 但它的实现原理究竟是什么?本文将揭开其底层三大黑科技。...二、ViewModelStoreOwner:多组件共享的“数据枢纽” 场景痛点 传统开发中,Activity与Fragment间的数据传递需要通过Bundle或接口回调,而ViewModel通过ViewModelStoreOwner...三、SavedStateHandle:进程级重建的“最后防线” 突破性能力 ViewModel默认只能抵御配置变更,但进程被系统杀死时数据仍会丢失。...通过集成SavedStateHandle,可将数据写入系统管理的Bundle,实现跨进程销毁的数据恢复。
上面这个是引用fragment-ktx的引用,引用这个库时是为了让我们更简单的调用ViewModel,一会儿的代码我会写出不用这个的调用方法,和用这个的方法,当然引用这个时它会提示要使用jvm1.8,所以还需要加上下面的这步...* 功能模块说明: */ class TestViewModel(val handle: SavedStateHandle) : ViewModel() { val mCount: MutableLiveData...TestViewModel继承自ViewModel,传入时加入了一个SavedStateHandle的参数,就是把我们程序被杀死时保存的数据传入进来,通过set的方式写入,getlivedata的方法读出来...我们把要保存的数字和显示信息分别用count和showmsg定义为MutableLiveData,把get方法做为从SavedStateHandle中进行读写直接保存。...双向数据绑定的方式,就和Vue的方式是很像的 ? Button的事件也是在这里进行绑定的 ?
从最初发布的管理 Activity 和 Fragment 生命周期的Lifecycle 库和访问 SQLite 数据库的 Room 库,后来推出了 分页(Paging)、 导航(Navigation)...数据绑定可以理解为代码和 XML 标记语言之间的桥梁。 更快的编译速度 对开发者来说,处理界面中的数据绑定需要的时间成本不容忽视,我们现在将数据绑定注解处理的速度提高了 20%*。...如果只这样粗略地理解的话,ViewModel 和 SavedState 其实是一回事。然而并不是这样的。...ViewModel 用于: 保留应用对网络、数据库的请求 当作大型对象的缓存 SavedState 用于: UI 的状态记录,比如选择区域和滚动距离等 导航状态键值记录 各取所长,联手打造流畅体验 //...SavedStateHandle class UserViewModel(val handle: SavedStateHandle) : ViewModel() { } 复制代码 现在用户的 ViewModel
(SavedStateHandle) 这两种的 ViewModel 。...通过名字我们就能知道, SavedStateHandle 是用来处理进程销毁等重建情况的数据恢复的。...从这里我们也可以知道,ViewModel 之前在进程被系统终止之后其实是不会保存数据给 ViewModel 的,在添加了 SaveStateHandle 之后才支持。...VIewModel 之前只支持屏幕旋转之类的重建场景的数据恢复功能,在 Activity 1.1.0 和 Fragment 1.2.0 之后,也支持进程回收等情况的数据恢复功能。...有类似需求的时候可以通过定义 ViewModel 中加入 SavedStateHandle 参数来实现。
除此之外,ViewModelComponent 还默认绑定了一个与 ViewModel 关联的 SavedStateHandle。...中,可以获得更好的灵活性和更精细的控制粒度。...@ViewModelScoped // 将类型的作用域限定为 ViewModel class UserInputAuthData( private val handle: SavedStateHandle...ViewModel,RegistrationViewModel 和 LoginViewModel 将获得 不同的 UserInputAuthData 实例。...由于 ViewModel 的生命周期可以被 Activity、Fragment 甚至是 导航图 所控制,您可以根据需要将作用域限定到这些地方,来获得更大的灵活性和更精细的控制粒度。
大家好,我是稳稳,一个曾经励志用技术改变世界,现在为随时失业做准备的中年奶爸程序员,与你分享生活和学习的点滴。 眼下正是奋战金三银四的时候,学习不能停啊!...数据层:使用Kotlin Flow构建背压感知的消息管道,避免OOM 2. 业务层:通过StateFlow实现消息优先级分流(如礼物>弹幕>点赞) 3....状态管理:用SavedStateHandle解决屏幕旋转后LiveData重置问题 2. 双向绑定:通过BindingAdapter实现自定义View与ViewModel通信 3....防内存泄漏:在ViewModel中使用CoroutineScope(SupervisorJob()) 高频面试题: “如何检测MVVM架构中的内存泄漏?”...Level 1(15k):能在Activity中完成功能开发 Level 2(25k):会使用MVVM+LiveData解耦业务 Level 3(40k+):能设计支持动态模块加载的响应式架构
最后一个参数是一个带接收者的Lambda表达式,这个lambda表达式的接收者是LiveDataScope,可以直接在代码块中(1处)中调用其emit方法,向LiveData发值。...小透明SavingStateLiveData 这个类的位置在 lifecycle-viewmodel-savedstate的SavedStateHandle类中,也是继承自MutableLiveData...private String mKey; private SavedStateHandle mHandle; 作用是保证,LiveData所在的Viewmodel重建时,能够拿到销毁前的数据。...CoroutinLiveData出场自带所宿主的ViewModel MediatorLiveData能同时监听多个LiveData的数据变化。...SavingStateLiveData销毁重建时能够自动恢复销毁前的数据。
对于搞Java的我来说,前端JS我是有点愚冻,今天在我的博客地盘我就悄悄发布一篇没有技术含量的文章,这次怎么说我也是完完整整的把公司后台管理系统的菜单异步加载独自搞出来了,对自己也是一个小小的提升,...同志们都知道,后台系统嘛无非就是一套模板样式,分为头文件,左侧菜单和主体内容,在多了就加个页脚文件。...但是为了提升系统的性能,很多公司都习惯将系统的目录数据放在缓存,然后通过异步请求的方式单独加载出来,我们公司也不例外。 首先系统欢迎页面中包含左侧菜单jsp文件,代码如下: 1 2 其次左侧菜单jsp文件中通常会加载一个js文件,因为系统的目录数据一般是通过js文件中的...version=1.0"> 最后,就是幕后黑手出场,饶了小半圈儿就是js文件加载目录数据的,不多解释,今儿心情好,代码原样粘贴: 1 $(function(){ 2 /
constructor( private val savedStateHandle: SavedStateHandle, /*…Hilt 关注的其他依赖项... */ ) : ViewModel...当这与 Android 开发中各种复杂的可感知生命周期组件一起使用时,就可能出现很多陷阱,例如内存泄漏: 作用域为 Activity 的依赖项被意外地传递到 ViewModel 中。...Dagger 和 Hilt 可以共存,应用可以基于需要进行 迁移。 更少的模板代码 Hilt 是被定制过的——这意味着为了减少您编写代码,它替您做了一些决定。...到目前为止,我们为 ViewModel、WorkManager、Navigation 和 Compose 提供直接注入支持。 参阅 文档,了解更多关于 Jetpack 的支持。...我非常感激 Hilt 与 ViewModel 一起开箱即用的使用方式,以及它消除单纯使用 Dagger 时必须设置的 ViewModel.Factory 模板代码的方式。
3 — 分页加载显示数据内容 Paging 开发库可以帮助分页加载显示数据内容。...我们发布了使用 Kotlin 的协程重写的 Paging 3。新版本添加了一些呼声较高的新功能,比如分隔符、标头和页脚,以及数据转换。...此外,新版本还添加了用来监控列表加载状态的一系列的 API,以及重试和刷新的方法等。...API,通过它可以在 SavedStateHandle 中查询和设置所有回退栈的入口。...新版本添加了许多新功能,包括视图组件的互通性、更多的 Material UI 组件、支持深色主题、新的 UI 测试和动画 API、对于 ConstraintLayout 的支持、优化状态管理、集成可观察的数据流和
Hilt 是什么 Hilt 是 Android 的依赖注入库,其实是基于 Dagger 。可以说 Hilt 是专门为 Andorid 打造的。 Hilt 创建了一组标准的 组件和作用域。...ViewModel 的使用 使用之前需要在 app.build 下添加一下对 viewModel的支持 implementation 'androidx.hilt:hilt-lifecycle-viewmodel...SavedStateHandle 使用 @Asssisted 注解 class HomeContentViewModel @ViewModelInject constructor( private...val response: HomeContentRepository, @Assisted val state: SavedStateHandle ) : ViewModel() {...} 复制代码 Hilt 和 Room 的使用 这里需要用到 @Module 注解,使用 @Module 注解的普通类,在其中提供 Room 的实例。
领取专属 10元无门槛券
手把手带您无忧上云