作者:何甜甜在吗 来源:http://1t.click/a7Gm 在项目开发过程中经常遇到时间处理,但是你真的用对了吗,理解阿里巴巴开发手册中禁用static修饰SimpleDateFormat...通过阅读本篇文章你将了解到: 为什么需要LocalDate、LocalTime、LocalDateTime【java8新提供的类】; java8新的时间API的使用方式,包括创建、格式化、解析、计算、...在多并发情况下使用SimpleDateFormat需格外注意 SimpleDateFormat除了format是线程不安全以外,parse方法也是线程不安全的。...calb中中属性设置cal c、返回设置好的cal对象 但是这三步不是原子操作 多线程并发如何保证线程安全 - 避免线程之间共享一个SimpleDateFormat对象,每个线程使用时都创建一次SimpleDateFormat...对象 => 创建和销毁对象的开销大 - 对使用format和parse方法的地方进行加锁 => 线程阻塞性能差 - 使用ThreadLocal保证每个线程最多只创建一次SimpleDateFormat对象
三个步骤就定义了使用LiveData的方式,从步骤可以看出,使用了观察者模式,当LiveData对象持有数据发生变化,会通知对它订阅的所有处于活跃状态的订阅者。...创建LiveData对象 LiveData可以包装任何数据,包括集合对象。LiveData通常存储在ViewModel中,并通过getter方法获得。...ViewModel持有LiveData而不是Activity或者Fragment中呢?...这样导致Activity或Fragment代码臃肿,Activity或Fragment一般用来展示数据而不是持有数据。...例如我们在实际开发中,我们的数据源要么来自服务器,要么来自本地数据库。这里就考虑使用MediatorLiveData。
每次应用程序数据更改时,你的观察者都可以在每次更改时更新 UI,而不是更新 UI 没有内存泄露 观察者绑定到 Lifecycle 对象,并在其相关生命周期被破坏后自行清理 不会因为活动停止而崩溃 如果观察者的生命周期处于非活动状态...例如,后台活动在返回前台后立即接收最新数据 配置更改友好 如果由于配置更改(例如设备轮换)而重新创建活动或片段,则会立即接收最新的可用数据 资源共享 你可以使用单例模式扩展 LiveData 对象以包装系统服务...LiveData 对象连接到系统服务一次,然后任何需要该资源的观察者都可以只观看 LiveData 对象 使用 LiveData 使用 LiveData 的常规步骤如下,我们按照下面这些步骤写一个简单的例子...LiveData 对象通常存储在ViewModel 对象中,并通过 getter 方法访问,如以下示例所示: class NameViewModel : ViewModel() { private...与 Room 一起使用 LiveData Room 持久化库支持可观察查询并返回 LiveData 对象,这些查询一般在 DAO 中编写 在更新数据库时,Room 会生成更新 LiveData 对象所需的所有代码
为了解决这个问题,我们还需要再使用一个remember函数。事实上,remember和mutableStateOf在Composable函数中几乎永远都是配套使用的。...既然都是Int了,那么我们就可以直接对这个值进行读写操作了,而不用像之前那样再调用它的getValue()和setValue()函数,是不是代码变得更简单了?...而状态提升就是这种单向数据流模式在Compose中的具体应用。 关于状态提升最后还有一个问题。既然我们可以将状态提升到上一层,那么是不是还可以再往上提一层,再往上呢?提到哪一层才能算结束?...但是传统LiveData的用法在Compose中并不好使,因为传统LiveData依赖于监听某个值的变化,并对相应的界面进行更新,而Compose的界面更新则依赖于重组。...因此我们在incrementCount()和incrementDoubleCount()函数里可以直接对其加1加2,而不用像之前LiveData那样写一段很奇怪的空指针保护代码了。
并且在 Kotlin 协程的加持下,Kotlin Flow 目前是 Google 主推的数据流框架。 1. 为什么要使用 Flow?...为什么我们可以把 SharedFlow 理解为 “高配版” LiveData,拿 SharedFlow 和 LiveData 做个简单的对比就知道了: 容量问题: LiveData 容量固定为 1 个,...当然 SharedFlow 也并不是完胜,LiveData 能够处理生命周期安全问题,而 SharedFlow 不行(因为 Flow 本身就不是纯 Android 生态下的组件),不合理的使用会存在不必要的操作和资源浪费...Google 的建议 是优先使用 Flow 而不是 Channel,主要原因是 Flow 会更自动地关闭数据流,而一旦 Channel 没有正常关闭,则容易造成资源泄漏。...浅尝一下 到这里,LiveData、Flow 和 Channel 我们都讲了一遍了,实际场景中怎么使用呢,浅尝一下。
在项目中,我们常常要定义圆角矩形背景,一般是用自定义drawable实现的 但是圆角矩形的背景与圆角常常会有细微的变化,而一旦变化我们又要新创建一个drawable文件 这样就会导致文件爆炸的问题...reified,通过添加类型传递简化泛型参数 这样就不用手动传泛型的类型过去了 Gson解析例子 我们首先看下一般我们使用gson解析json是怎么做的 在Java序列化库(如Gson)中,当您想要反序列化该...由于新的类继承了具体的 ArrayList 类而不是实现 MutableList 接口,因此它与 ArrayList 的实现高度耦合。...这一特性在您需要在其他对象间复用 getter/setter 逻辑时十分有用,同时也能让您可以轻松地对简单支持字段的功能进行扩展 举个例子,利用委托属性可以封装SharedPreference 将数据存储操作委托给代理类有几个好处...3.在类里面声明一些可空的函数类型的可变(var)私有成员变量,并且在回调函数中拿到对应的变量实现它的invoke函数,传入对应的参数。
换句话说,我们可以在监听 LiveData 的时候,拿到监听之前设置给 LiveData 的值 —— 我们称之为粘性消息。 但是有时候,我们并不希望在监听的时候拿到「上一次的值」。...LiveData 的这种特性,这并不是一个 Bug,LiveData 设计之初并不是给我们用来当成 EventBus 使用的,而是用于监听「状态」的,此处引用官博的原文 Instead of trying...因此,并不是所有场景下都适合使用 LiveData,当我们所要监听的数据是符合「状态」特性,而是不是「事件」特性的时候,才是最适合使用 LiveData 的场景。...LiveData 常见的几种错误使用姿势 前文之所以花费这么大篇幅介绍 LiveData 的「粘性消息」特性,一是为了让大家对 LiveData 有更深一步的认识,了解其设计之初的目的才知道什么时候该用...(this, observer1) viewModel.liveData.observe(this, observer2) } } 复制代码 我们在 observer1 中修改了
请注意,数据不是自动为你组合的,MediatorLiveData只是负责通知的工作。 为了在我们的示例应用程序中实现转换,我们需要将两个不同的LiveDatas合并成一个。...在ViewModel中,我们需要公开一个randomNumber属性,从生成器中获取数字。为此使用MediatorLiveData并不理想,因为它要求你在每次需要新数字时都要添加源。...然而,我们正在泄露所有以前的LiveDatas,这些LiveDatas不会再发送更新,所以这是一种浪费。 你可以存储一个对源的引用,然后在添加新的源之前将其删除。...观察者只在订阅的时候接收分配给var的LiveData的更新,这是非常常见的。...不要在var中使用Livedata。在初始化的时候,要将转换的内容写入。
停止而导致崩溃 不再需要手动处理生命周期 数据始终保持最新状态 可以用来做资源共享 Livedata 使用 一般来说我们会在 ViewModel 中创建 Livedata 对象,然后再 Activity.../Fragment 的 onCreate 中注册 Livedata 监听(因为在 onStart 和 onResume 中进行监听可能会有冗余调用) Livedata 简单使用 仍然还是用我们倒计时的例子...Livedata 在多个视图监听状态 本例实现的 demo 效果是,创建一个全局的倒计时,然后在 Activity 中添加两个按钮,点击后可以切换 FragmentA 和 FragmentB。...} } data class User(var name:String,var age:Int) 代码中 mapLiveData 是对 userLivedata 进行转换得到的,所以当我们调用...Livedata 和协程联合使用 emit 方式使用 引入依赖 有时候你可能需要处理异步任务,任务处理完成后刷新 ui 这种情况可以使用 Livedata 的扩展程序实现 本例我们实现下面的逻辑: 在
但有了ViewModel+LiveData,我们就不必再处理这个问题了。这就是为什么我们在《应用程序架构指南》中推荐这种方法。...而排列文本在作用于ViewModel的操作中是没有意义的,因为在旋转之后,你的文本容器可能已经改变了形状。 显然,现实世界中的应用可以有比这些更多的作用域。...例如,在Android Dev Summit应用程序中,我们可以使用。...因此,我们可以从数据源和存储库中暴露Flow,而不是LiveData,但ViewModel仍然暴露LiveData,因为它是生命周期感知的。...LiveData: Suspend transformation 比方说,你想对来自数据源的东西进行转换,但它可能是CPU密集型的,所以它是在一个suspend函数中。
reified,通过添加类型传递简化泛型参数 这样就不用手动传泛型的类型过去了 Gson解析例子 我们首先看下一般我们使用gson解析json是怎么做的 在Java序列化库(如Gson)中,当您想要反序列化该...由于新的类继承了具体的 ArrayList 类而不是实现 MutableList 接口,因此它与 ArrayList 的实现高度耦合。...这一特性在您需要在其他对象间复用 getter/setter 逻辑时十分有用,同时也能让您可以轻松地对简单支持字段的功能进行扩展 举个例子,利用委托属性可以封装SharedPreference 将数据存储操作委托给代理类有几个好处...by bindToPreferenceFieldNullable() } 带状态的LiveData 目前我们在开发的过程中越来越多的使用MVVM模式与ViewModel 我们也常常用LiveData来标识网络请求状态...3.在类里面声明一些可空的函数类型的可变(var)私有成员变量,并且在回调函数中拿到对应的变量实现它的invoke函数,传入对应的参数。
现在接收的是Flow而不是LiveData,所以它需要进行调整:不是观察LiveData,而是收集Flow。...在这种情况下,你可以通过使用Flow.asLiveData()扩展函数在ViewModel中轻松地从Flow转换为LiveData。...如果我们期望操作只做一次,以保证正确性,它甚至可能导致错误的状态。在我们的实际例子中,我们将为每个采集器添加一个新的GeoQuery监听器--可能不是一个关键问题,但肯定是在浪费内存和CPU周期。...关于术语的注意:就像我们对LiveData使用观察者这个术语,对冷流使用收集者这个术语一样,我们对SharedFlow使用订阅者这个术语。...StateFlow对SharedFlow的约束可能不是最适合你的,你可能想用行为来调整并选择使用SharedFlow。
你可以使用asLiveData扩展函数在ViewModel中把Flow转换为LiveData。...❝注意:如果你在资源库中没有使用Flow,你可以通过使用liveData builder实现同样的数据转换功能。...-252ec15cc93a 在第一部分中,我们已经看到了如何在资源库层中使用Flow,以及如何用Flow和LiveData改变应用程序的主题。...asLiveData将Flow转换为LiveData,而只是在ViewModel中使用Flow。...如果你有一个长期运行的运算符,你可以使用buffer,这样直到buffer的所有运算符的执行将在一个不同的coroutine中处理,而不是在协程中对Flow collect。这使得总的执行速度更快。
LiveData的粘性机制会带来副作用,但这本身并不是LiveData的设计缺陷,而是对它的过度使用。 Kotlin Flow是基于kotlin协程的一套异步数据流框架,可以用于异步返回多个值。...项目由MVP过渡到MVVM时,其中一个典型的重构手段就是将Presenter中的回调写法改写成在ViewModel中持有LiveData由View层订阅,比如以下场景: 在大力自习室中,当老师切换至互动模式时...但选型时我们要考虑以下问题,也是LiveData被推荐使用的优势 : 是否会发生内存泄漏,观察者的生命周期遭到销毁后能否自我清理 是否支持线程切换,比如LiveData保证在主线程感知变化并更新UI 不会在观察者非活跃状态下消费事件...MVVM并没有约束View层与ViewModel的交互方式,具体来说就是View层可以随意调用ViewModel中的方法,而MVI架构下ViewModel的实现对View层屏蔽,只能通过发送Intent...结论 架构中对SharedFlow和channelFlow的使用绝对值得保留,就算不使用MVI架构,参考这里的实现也可以帮助解决很多开发中的难题,尤其是涉及横竖屏的问题。
官网商城app团队在深度使用LiveData的过程中,也遇到了一些困难,尤其是在LiveData的观察者使用上踩到了不少坑,我们把这些经验在这里做一次总结与分享。...二、Observer到底可以接收多少次回调 2.1 为什么最多收到2个通知 这是一个典型的案例,在调试消息总线的场景时,我们通常会在消息的接收者那里打印一些log日志方便我们定位问题,然而日志的打印有时候也会给我们的问题定位带来一定的迷惑性...我们创建了一个Livedata,然后对这个Livedata Observe了10次,每次都是new出不同的Observer对象,看上去我们对一个数据源做了10个观察者的绑定。...Java8 lambda的写法,所以编译器在编译的过程中自作聪明了一下,自动帮我们优化成都是添加的同一个静态的观察者,并不是10个,这就解释了为什么会出现map size为1的情况了。...在今年的谷歌I/O大会中,Yigit 在Jetpack的 AMA 中明确指出了 Livedata的存在就是为了照顾Java的使用者,短期内会继续维护(含义是什么大家自己品品),作为Livedata的替代品
而我们传统的处理办法就是在配置变更期间保留对象和自行处理配置变更这两种,这两种方式都有很多坑(看看官方文档就知道了),尤其是需要恢复的数据比较多的时候,而 ViewModel 就非常适合处理这些情况 在下图中...,但我强烈推荐你综合使用整套架构组件,除非你的项目有严格限制或其它特殊情况 前面的 Demo 为了快速理解 ViewModel 的用法所以写的非常简单,接下来我们将使用 Timer + LiveData...= null private val _elapsedTime = MutableLiveData() var elapsedTime: LiveData = _...= null private val _elapsedTime = MutableLiveData() var elapsedTime: LiveData = _...ONE_SECOND = 1000L } } 3、在 Activity 中订阅 elapsedTime 如下代码,我们使用 viewModel.elapsedTime.observe(owner
View订阅LiveData中的变化,并对其做出反应。这对于在屏幕上连续显示并可能会修改的数据来说是非常有效的手段。...你的观察者可以在每次应用数据变化(生命周期变化)时更新UI,而不是在每次有变化时更新UI。 没有内存泄漏:观察者被绑定到生命周期对象,并在其相关的生命周期被销毁时进行自我清理。...Jose的解决方案缺乏对多个观察者的支持,而这正是LiveData以 "共享资源 "为名的承诺之一。 它不是线程安全的。 我还可以补充一个问题。...通过使用LiveData,我们希望在代码中使用函数式编程的优势,而函数式编程的原则之一是使用不可变的数据结构。这个原则将被Jose推荐的解决方案所打破。...第三,在removeObserver方法中,我们希望有一个ObserverWrapper,我们已经在observe方法中注册了这个ObserverWrapper,并且我们在observices中设置了它来移除
前言 ViewModel和LiveData最早是Google提出的AAC架构中的重要成员,那么它为什么又和协程扯上关系了呢?...后语 在确定了学习LiveData并不是无用功之后,我们来看下如何在实际场景下利用这两兄弟来提高我们的开发效率。...中,不用对LiveData进行销毁。...的协程构造器提供了一个协程代码块,这就是LiveData的协程作用域,当LiveData被注册的时候,作用域中的代码就会被执行,而当LiveData不再被使用时,里面的操作就会因为结构化并发而取消。...而且该协程构造器返回的是一个不可变的LiveData,可以直接暴露给对应的UI层使用,在作用域中,可以通过emit()函数来更新LiveData的数据。 这样整体流程就通了,而且,非常简单不是吗?
而如果谈到在Flow的所有概念当中,最最接近LiveData的,那毫无疑问就是StateFlow了。 可以说,StateFlow的基本用法甚至能够做到与LiveData完全一致。...然后,这里通过lifecycleScope启动了一个协程作用域,并开始对我们刚才定义的StateFlow进行监听。上述代码中的collect函数相当于LiveData中的observe函数。...而如果此时观察者收不到之前的消息,那么这种行为就叫做非粘性。 EventBus允许我们在使用的时候通过配置指定它是粘性的还是非粘性的。而LiveData则不允许我们进行指定,它的行为永远都是粘性的。...粘性特性在绝大多数场景下都非常好使,这也是为什么LiveData和StateFlow都设计成粘性的原因。 但确实在一些场景下,粘性又会导致出现某些问题。...而LiveData并没有提供非粘性的版本,所以网上甚至还出现了一些用Hook技术来让LiveData变成非粘性的方案。 相比之下,Flow则人性化了很多。想要使用非粘性的StateFlow版本?