今天知道LiveData的ktx是真的香
主要还是认知问题,Android 官网从一开始就在推ktx,现在都已经2.+ 版本了,但是呢,因为之前没有从0开始写过一个Kotlin的APP,就陷入了一个JAVA 思维,在JAVA 中我们知道要做到像协程这么处理不是不能,只是过于复杂,一般水平的人根本驾驭不住,恰巧,我根本不敢想。也就导致了一个问题,ktx 这个界面路过了无数次,今天终于看到了TA。
什么痛点?
写过界面base 的同学可能有经验,如果是说,想要在viewModel 创建的时候,就开始进行异步进行网络请求,除了要处理构造函数传递进来的入参,还有要处理viewModel的Factory,就是说,viewModel想要通过构造函数传参,Factory 的重写成自己的,但是我们又没法确定后续的viewModel的构造是啥,init执行的时候,属性变量都还没有赋值,所以在init 里面写,逻辑就根本行不通,就只能在Lifecycle里面写,当生命周期到什么时候,就主动调用这个viewModel规范好的内容,然后通过liveData 和泛型把数据抛给用户层。
上面是理想情况,现实情况并不是这个样子的,因为有些界面接口请求并不是一个,可能是多个请求顺序执行,而且,每个人都有自己的想法,嗯,我们通常的认为别人可以理解自己的想法,所以,base是不写注释,所以写了别人不用还说写的垃圾,为了更贴合大众实际思路,我们可能提供几个函数:
fun observe()
fun initView(savedInstanceState: Bundle?)
fun initData()
然后再 initData 里面自己写网络请求。这就很烦人,经常搬砖的同学都知道,一个界面就一个网络请求是常态,但是他不是必然因素,每个界面都要自己写initData,我写多了也骂自己垃圾,为啥不封装一下,当然更多的时候是骂包这个玩意的人。
如何解决这个痛点
既然kotlin的扩展函数这么强大能不能自己包装一个什么东西,比如我们是通过liveData 进行数据监听,我们创建LiveData 的时候,就在协程里面请求数据,然后发送出去,这个时候,构造函数也执行完了,也不担心init 执行的时候 属性变量没有赋值的问题,所以就开整:
val pageData = getNetLiveData()
fun getNetLiveData(): LiveData<String> {val live = MutableLiveData<String>()viewModelScope.launch(Dispatchers.IO) {val params = mutableMapOf<String, String>()params.put("keywords", "")val json = OkHttpImpl.postSting("这是网络请求地址",params)live.postValue(json)}return live
}
思路是,我们pageData 的对象通过函数getNetLiveData 创建,然后在函数getNetLiveData 里面直接创建一个协程 请求网络,请求成功了,把数据抛出去,这只是基础概念,我们还可以抽离成泛型,抽离一个作用域函数啥的。
ktx 如何解决这个问题
当完成泛型抽离,想做作用域抽离的时候,灵光一闪,这玩意我见过。
val user: LiveData<Result> = liveData {emit(Result.loading())try {emit(Result.success(fetchUser()))} catch(ioException: Exception) {emit(Result.error(ioException))}
}
这ktx 已经提供好了好吧。那么就直接用就行。直接在 mvnrepository liveData-ktx 最小版本,导入使用即可。
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2")
例如这样:
val liveData: LiveData<String> = liveData(Dispatchers.IO) {val params = mutableMapOf<String, String>()params.put("keywords", "")val json = OkHttpImpl.postSting("https://..........",params)emit(json)
}
如何解决刷新
那么如何做到刷新呢?我们界面通常是有刷新的对吧,我们总不能刷新的时候重新创建 liveData 然后重新设置监听吧。 所以我们需要正确的抽离业务逻辑。我们知道MutableLiveData可以通过setValue 或者post 发送多次消息,而LiveData 这个类因为函数是私有的,所以说,这个玩意并不能被外部调用。我们看下 liveData{} 函数的实现:
public fun <T> liveData(context: CoroutineContext = EmptyCoroutineContext,timeoutInMs: Long = DEFAULT_TIMEOUT,block: suspend LiveDataScope<T>.() -> Unit
): LiveData<T> = CoroutineLiveData(context, timeoutInMs, block)
CoroutineLiveData的实现:
internal class CoroutineLiveData<T>(context: CoroutineContext = EmptyCoroutineContext,timeoutInMs: Long = DEFAULT_TIMEOUT,block: Block<T>
) : MediatorLiveData<T>()
OK,到这里,基本就清晰了,但是还是贴一下:
public class MediatorLiveData<T> extends MutableLiveData<T> {}
所以说,liveData{} 这个函数返回的其实是MediatorLiveData 对象,如果不熟悉这个玩意,但是MediatorLiveData的父类MutableLiveData是熟悉的。
代码看到这里,我们需要刷新的逻辑就非常清晰了,我们将liveData{} 函数的返回参数 通过as 转化为 MediatorLiveData或MutableLiveData即可。MediatorLiveData是用于监听多个值得变化的,用的比较少,比如说,用于多接口并发请求,统一返回,比如说类型转化,服务器数据模型与本地数据模型不一致的情况,再比如说监听界面变化等。我们这里直接就强制转换为 MutableLiveData:
val livedataKtx= liveData<String> {emit("luoye")
} as MutableLiveData<String>
在刷新的时候:
fun refresh(){livedataKtx.value="luoye"
}
使用KTX 库的好处还是非常明显的,比如我们不需要自己写协程切换,当然自己扩展函数抽离得好,也不是不行。
最后
其实,LiveData 要写,还是有很多知识点可以写的,但是这里只是进行了简单的逻辑的概述吧。我们通过属性变量的创建时机去进行接口请求或者缓存请求,那么在一定程度上是要比调用initData 更快的,而且这种逻辑非常清晰,我们将首次和刷新从逻辑层分离出来,这种代码看起来还是非常简洁的。
在这个逻辑上,我们可以发现compose 的中的界面数据,通过这种方式的刷新,反而更加的贴合吧。当然通过Flow,或者channel 等方式 转LiveData 也是一种思路,但是在简单的界面请求中,感觉没有必要。
Android 学习笔录
Android 性能优化篇:https://qr18.cn/FVlo89
Android Framework底层原理篇:https://qr18.cn/AQpN4J
Android 车载篇:https://qr18.cn/F05ZCM
Android 逆向安全学习笔记:https://qr18.cn/CQ5TcL
Android 音视频篇:https://qr18.cn/Ei3VPD
Jetpack全家桶篇(内含Compose):https://qr18.cn/A0gajp
OkHttp 源码解析笔记:https://qr18.cn/Cw0pBD
Kotlin 篇:https://qr18.cn/CdjtAF
Gradle 篇:https://qr18.cn/DzrmMB
Flutter 篇:https://qr18.cn/DIvKma
Android 八大知识体:https://qr18.cn/CyxarU
Android 核心笔记:https://qr21.cn/CaZQLo
Android 往年面试题锦:https://qr18.cn/CKV8OZ
2023年最新Android 面试题集:https://qr18.cn/CgxrRy
Android 车载开发岗位面试习题:https://qr18.cn/FTlyCJ
音视频面试题锦:https://qr18.cn/AcV6Ap
相关文章:
今天知道LiveData的ktx是真的香
主要还是认知问题,Android 官网从一开始就在推ktx,现在都已经2. 版本了,但是呢,因为之前没有从0开始写过一个Kotlin的APP,就陷入了一个JAVA 思维,在JAVA 中我们知道要做到像协程这么处理不是不能࿰…...
SpringBoot中的桥接模式
桥接模式是一种结构型设计模式,它的主要目的是通过将抽象部分与实现部分分离,提高系统的灵活性和可扩展性。在桥接模式中,有四个主要参与者:抽象类、具体抽象类、桥接类和具体类。 抽象类是定义了抽象方法的基类,这些…...
AI爆文变现脚本:易用且免费的自动写作脚本更新了
之前给大家分享的AI爆文变现写作脚本 由于时间仓促,加上我对很多东西不熟悉 免费版本对新手小白来说,安装部署起来是非常的困难 于是这几天我加班加点把整个软件的部署简化 现在无需复杂的环境配置安装,下载配置下就可以使用了。 免费版…...
代码随想录算法训练营Day 49 || 123.买卖股票的最佳时机III 、188.买卖股票的最佳时机IV
123.买卖股票的最佳时机III 力扣题目链接(opens new window) 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。 注意:你不能同时参与多笔交易(你必须…...
threejs(11)-精通着色器编程(难点)2
一、shader着色器编写高级图案 小日本国旗 precision lowp float; varying vec2 vUv; float strength step(0.5,distance(vUv,vec2(0.5))0.25) ; gl_FragColor vec4(strength,strength,strength,strength);绘制圆 precision lowp float; varying vec2 vUv; float strength 1…...
配置cuda和cudnn出现 libcudnn.so.8 is not a symbolic link问题
cuda版本为11.2 问题如图所示: 解决办法: sudo ln -sf /usr/local/cuda-11.2/targets/x86_64-linux/lib/libcudnn_adv_train.so.8.1.1 /usr/local/cuda-11.2/targets/x86_64-linux/lib/libcudnn_adv_train.so.8 sudo ln -sf /usr/local/cuda-11.2/targ…...
“目标值排列匹配“和“背包组合问题“的区别和leetcode例题详解
1 目标值排列匹配 1.1 从目标字符串的角度来看,LC139是一个排列问题,因为最终目标子串的各个字符的顺序是固定的? 当我们从目标字符串 s 的角度来看 LC139 “单词拆分” 问题,确实可以认为它涉及到排列的概念,但这种…...
火星加载WMTS服务
这是正常的加载瓦片 http://192.168.1.23:8008/geoserver/mars3d/gwc/service/wmts?tilematrixEPSG%3A4326%3A7&layermars3d%3Abuffer&style&tilerow46&tilecol197&tilematrixsetEPSG%3A4326&formatimage%2Fpng&serviceWMTS&version1.0.0&…...
为什么要学习去使用云服务器,外网 IP能干什么,MAC使用Termius连接阿里云服务器。保姆级教学
目录 引言 可能有人想问为什么要学习云服务器? (获取Linux环境,获得外网IP) 二、安装教程 引言 可能有人想问为什么要学习云服务器? (获取Linux环境,获得外网IP) 1.虚拟机(下策) …...
VS c++多文件编译
前言:记录下我这个菜鸡学习的过程,如有错误恳请指出,不胜感激! 1.简单多文件编译调试 文件目录: 编译: -g选项是告诉编译器生成调试信息,这样可以在程序崩溃或出现错误时更容易地进行调试。这…...
JVM关键指标监控(调优)
JVM 99%情况下不需要调优 使用性能更好的垃圾回收器 核心指标 针对单台服务器而言: jvm.gc.time: 每分钟GC耗时在1s以内 500ms以内最佳 jvm.gc.meantime: 每次YGC耗时在100ms以内,50ms以内最佳 jvm.fullgc.count: FGC(老生代垃圾回收)最多几小时1次&…...
【Proteus仿真】【Arduino单片机】LCD1602-IIC液晶显示
文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器,使用PCF8574、LCD1602液晶等。 主要功能: 系统运行后,LCD1602液晶显示各种效果。 二、软件设计 /* 作者:嗨小…...
skynet学习笔记03— 服务
01、API newservice(name, ...): 阻塞的形势启动一个名为 name 的新服务,待start函数执行完后会返回这个服务的地址。uniqueservice(name, ...):针对于当前节点,启动一个唯一服务(相当于单例),…...
34 Feign最佳实践
2.4.2.抽取方式 将Feign的Client抽取为独立模块,并且把接口有关的POJO、默认的Feign配置都放到这个模块中,提供给所有消费者使用。 例如,将UserClient、User、Feign的默认配置都抽取到一个feign-api包中,所有微服务引用该依赖包…...
软文推广中如何搭建媒体矩阵
媒体矩阵简单理解就是在不同的媒体平台上,根据运营目标和需求,建立起全面系统的媒体布局,进行多平台同步运营。接下来媒介盒子就来和大家聊聊,企业在软文推广过程中为什么需要搭建媒体矩阵,又该如何搭建媒体矩阵。 一、…...
Unity地面交互效果——5、角色足迹的制作
大家好,我是阿赵。 之前几篇文章,已经介绍了地面交互的轨迹做法。包括了法线、曲面细分还有顶点偏移。Shader方面的内容已经说完了,不过之前都是用一个球来模拟轨迹,这次来介绍一下,怎样和角色动作结合,…...
Centos8安装出错问题
科普介绍: CentOS 8 是一个基于 Linux 的操作系统,是 Red Hat Enterprise Linux (RHEL)的免费和开源版本。它提供了稳定、安全和可靠的基础设施,适用于服务器和桌面环境。CentOS 8 是 CentOS 系列中最新的版本&#x…...
计算机网络技术
深入浅出计算机网络 微课视频_哔哩哔哩_bilibili 第一章概述 1.1 信息时代的计算机网络 1. 计算机网络各类应用 2. 计算机网络带来的负面问题 3. 我国互联网发展情况 1.2 因特网概述 1. 网络、互连网(互联网)与因特网的区别与关系 如图所示࿰…...
当电脑桌面黑屏,而你只有一个鼠标该怎么办(重启方法的平替)
作为一个打工人 电脑是不是黑屏简直是routine了 我们都知道重启能解决一切问题 但是!! 如果你只有一个鼠标 电脑因为种种原因没法重启 该怎么办呢? 别慌 下面的方法非常灵验 1.按住ctrlShiftEsc 调出任务管理器;此项为必须…...
Leetcode2833. 距离原点最远的点
Every day a Leetcode 题目来源:2833. 距离原点最远的点 解法1:贪心 要使得到达的距离原点最远的点,就看 left 和 right 谁大,将 left 和 right 作为矢量相加,再往同方向加上 underline。 答案即为 abs(left - rig…...
memtest_vulkan:Vulkan计算着色器驱动的GPU显存稳定性测试架构解析
memtest_vulkan:Vulkan计算着色器驱动的GPU显存稳定性测试架构解析 【免费下载链接】memtest_vulkan Vulkan compute tool for testing video memory stability 项目地址: https://gitcode.com/gh_mirrors/me/memtest_vulkan 在GPU计算日益普及的今天&#x…...
RV1106开发板实战:手把手教你编译FFmpeg 3.4.8并集成到LVGL 9.2.3播放视频
RV1106开发板实战:从零构建FFmpeg 3.4.8与LVGL 9.2.3视频播放系统 在嵌入式设备上实现流畅的视频播放一直是开发者面临的挑战之一。RV1106作为一款高性能的嵌入式处理器,结合FFmpeg强大的多媒体处理能力和LVGL轻量级图形库的优雅界面,能够打造…...
从架构到应用:深度解析自回归语言模型(CLM)与大语言模型(LLM)的核心差异
1. 模型架构:单向生成与双向理解的本质差异 自回归语言模型(CLM)和大语言模型(LLM)最根本的区别在于架构设计理念。CLM采用严格的单向结构,就像我们平时说话一样逐字推进。我在调试GPT-2的生成过程时发现&…...
10分钟训练AI音色模型:RVC变声器终极实战指南
10分钟训练AI音色模型:RVC变声器终极实战指南 【免费下载链接】Retrieval-based-Voice-Conversion-WebUI Easily train a good VC model with voice data < 10 mins! 项目地址: https://gitcode.com/GitHub_Trending/re/Retrieval-based-Voice-Conversion-WebU…...
终极语音修复指南:用VoiceFixer让受损音频重获新生的完整教程
终极语音修复指南:用VoiceFixer让受损音频重获新生的完整教程 【免费下载链接】voicefixer General Speech Restoration 项目地址: https://gitcode.com/gh_mirrors/vo/voicefixer 你是否曾为珍贵的录音被噪音淹没而烦恼?那些因设备故障、环境嘈杂…...
Sora API:生成 AI 视频
简介 在数字内容创作日益重要的今天,视频生成技术逐渐成为开发者的热门选择。Sora API 是由 Ace Data Cloud 提供的一个强大工具,允许用户通过简单的 REST API 接口,将文本和图像转化为高质量的视频。无论是为社交媒体创建短视频,…...
Qwen3-0.6B-FP8镜像免配置部署:无需修改代码,直接运行start.sh启动服务
Qwen3-0.6B-FP8镜像免配置部署:无需修改代码,直接运行start.sh启动服务 想快速体验一个轻量级但功能完整的AI对话模型吗?今天给大家介绍一个“开箱即用”的解决方案——Qwen3-0.6B-FP8镜像。这个镜像最大的特点就是零配置,你不需…...
如何调试Qwen3-Embedding-4B?日志分析与错误定位实战教程
如何调试Qwen3-Embedding-4B?日志分析与错误定位实战教程 1. 引言:为什么需要调试Embedding模型? 当你使用Qwen3-Embedding-4B构建知识库时,可能会遇到各种问题:模型加载失败、向量生成异常、检索结果不准确等。这些…...
D3DCompiler_47.dll文件不存在 无法启动问题 教你免费下载方法
在使用电脑系统时经常会出现丢失找不到某些文件的情况,由于很多常用软件都是采用 Microsoft Visual Studio 编写的,所以这类软件的运行需要依赖微软Visual C运行库,比如像 QQ、迅雷、Adobe 软件等等,如果没有安装VC运行库或者安装…...
AIAgent架构治理的“最后一公里”:当LLM调用链遇上分布式事务——3种跨Agent一致性保障方案(含开源PoC代码)
第一章:AIAgent架构治理的“最后一公里”:当LLM调用链遇上分布式事务 2026奇点智能技术大会(https://ml-summit.org) 在多Agent协同推理场景中,单次用户请求常触发跨模型、跨服务、跨数据库的长链路LLM调用——从意图解析Agent调用RAG检索服…...
