下载:马SB-Python全栈工程师图解Python语法-2022最新完结Jetpack架构演进(一):流初用,追加经典案例在jetpack系统中livedata的作用livedata纯粹是一个桥梁。数据从DataSource中获取,然后由viewmodel进行逻辑处理,最后通过livedata.postValue发送到view层。唯一的价值在于绑定了生命周期,只在页面激活(start)时接受数据,可以参考官方的一篇介绍:MigratingfromLiveDatatoKotlinDataFlow-Nuggets对于初学者来说,使用lieveData的好处是它足够简单且相对安全。引入Flow的主要原因是:API更友好,学习成本更低,Kotlincoroutine和LiveData分离更紧密。Flow可以转化为LiveData,分离协程的作用域可以直接在ViewModel中使用。当协程被取消时,Flow也会被取消,以防止内存泄漏。library是kotlin的,livedata是Android的。请依靠Android平台的限制,有利于以后的跨平台开发【流量是冷数据流】所谓冷流量,就是当下游没有消费行为时,上游不会产生数据。只要下游开始消费,上游就开始产生数据。所谓热流,就是不管下游有没有消费行为,上游都会自己产生数据。下面通过一个经典场景详细描述flow(简单flow,stateFlow会在后续章节讲解)的用例:在一个菜谱应用app中,我想在一个页面上显示一个列表(recyclerview),以及此列表项中的每一项都是一个子列表,子列表是项目配方列表;珍贵食谱清单;根据配料选择的食谱列表;每个列表都可能是空的。如果是空列表,则不会显示该行。由于四个接口的数据大小不同,所以不会同时返回。同时需要保证四个子列表按照请求的顺序显示。.思路:设计数据结构,最外层数据:dataclassContainerData(valtitle:String,vallist:List)复制代码其中Recipe实体为数据类Recipe(valid:String,valname:String,valcover:String,valtype:Int,valingredients:List?=mutableListOf(),valminutes:Int,valpantryItemCount:Int)复制代码模拟四个请求为:valplannlist=Request.getPlannlist()valfavoritelist=Request.getFavouritelist()...等等。如果四个请求的返回顺序根据请求不同,并且请求在列表中按顺序显示,是否完成?方案一:可以等四个请求都返回后再组装数据。您可以使用协程的await方法来刷新列表:valdataList=MutableLiveData()viewModelScope.launch{//plannervalplannerDefer=async{Request.getPlannlist()}//favoritevalfavoriteDefer=async{Request.getFavouritelist()}valplannerData=plannerDefer.await()valfavoriteData=favoriteDefer.await()....省略后两个接口vallist=listof(Container("planner",plannerData),Container("favourite",favoriteData),...)数据列表.postValue(list)}复制代码await()方法是挂起协程,四个接口异步请求(非顺序),等待最后一个数据请求返回后再执行后面的步骤,然后组装数据发送使用liveData,在viewRenderingviewModel.dataList.observe(viewLifecycleOwner){mAdapter.submitList(it)}这种复制代码的方式简单有效的处理了四个列表依次排列的需求。缺点是体验差。假设一个界面特别慢,另外几个会等着,用户一直盯着loading?方案二:接口之间不再相互等待,先返回哪个接口就渲染哪个接口。问题是如何保证顺序?有的同学会有一个方案:先自定义一个空数据listvallist=listOf(Container("planner",emptylist()),Container("favourite",emptylist()),...)复制代码然后使用adapter去Renderlist,返回哪个界面就去之前的list中查找交换,然后adapter刷新对应的数据。当然可以,但是会生成一部分逻辑胶水代码来进行查找和遍历操作。此时我们可以使用flow来完成1构造一个planner数据流valplannerFlow=flow{valplannList=Request.getPlanlist()emit(ContainerData("Planner",plannList))}.onStart{emit(ContainerData("",emptylist()))}copycode注意是val变量,不要写成funplannerFlow()方法,否则每次调用新的stack都会新建一个flow,继续保持在内存中,直到协程被取消。在发送官方数据之前发送,作为预加载。那么我们就可以正式请求这个结构体)}}复制代码combine的官方注释是ReturnsaFlow,其值是通过合并每个流最近发出的值,用transform函数生成的。copycodecombineoperator可以连接两个不同的Flow,一旦数据产生,在有序的情况下触发组合流的activity。
