Compose笔记(十)--DataStore(一)

        这一节主要了解一下Compose中的DataStore,在Jetpack Compose中,DataStore是一种数据存储解决方案,用于以异步、一致的方式存储键值对或自定义类型的数据。它提供了替代SharedPreferences的更现代化、更安全的方案,也是一个基于Flow和Coroutines的异步数据存储解决方案。

 作用:    1 异步操作:避免在主线程上进行阻塞式的 I/O 操作,确保应用的流畅性。2 类型安全:Proto DataStore可以存储自定义的Protocol Buffers消息,提供类型安全的访问。 3 一致性:保证数据的一致性,避免了SharedPreferences可能出现的并发问题。

栗子:

添加依赖:

implementation("androidx.datastore:datastore-preferences:1.1.3")
import android.content.Context
import androidx.datastore.preferences.core.*
import androidx.datastore.preferences.preferencesDataStoreprivate const val PREFERENCES_NAME = "complex_preferences"private val Context.dataStore by preferencesDataStore(name = PREFERENCES_NAME)object PreferencesKeys {val USER_NAME = stringPreferencesKey("user_name")val USER_AGE = intPreferencesKey("user_age")val IS_PREMIUM_USER = booleanPreferencesKey("is_premium_user")val FAVORITE_COLORS = stringSetPreferencesKey("favorite_colors")
}
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.mapclass PreferencesManager(private val context: Context) {val userNameFlow: Flow<String?> = context.dataStore.data.map { preferences ->preferences[PreferencesKeys.USER_NAME]}val userAgeFlow: Flow<Int?> = context.dataStore.data.map { preferences ->preferences[PreferencesKeys.USER_AGE]}val isPremiumUserFlow: Flow<Boolean?> = context.dataStore.data.map { preferences ->preferences[PreferencesKeys.IS_PREMIUM_USER]}val favoriteColorsFlow: Flow<Set<String>?> = context.dataStore.data.map { preferences ->preferences[PreferencesKeys.FAVORITE_COLORS]}suspend fun saveUserName(name: String) {context.dataStore.edit { preferences ->preferences[PreferencesKeys.USER_NAME] = name}}suspend fun saveUserAge(age: Int) {context.dataStore.edit { preferences ->preferences[PreferencesKeys.USER_AGE] = age}}suspend fun saveIsPremiumUser(isPremium: Boolean) {context.dataStore.edit { preferences ->preferences[PreferencesKeys.IS_PREMIUM_USER] = isPremium}}suspend fun saveFavoriteColors(colors: Set<String>) {context.dataStore.edit { preferences ->preferences[PreferencesKeys.FAVORITE_COLORS] = colors}}suspend fun batchUpdatePreferences(name: String, age: Int, isPremium: Boolean, colors: Set<String>) {context.dataStore.edit { preferences ->preferences[PreferencesKeys.USER_NAME] = namepreferences[PreferencesKeys.USER_AGE] = agepreferences[PreferencesKeys.IS_PREMIUM_USER] = isPremiumpreferences[PreferencesKeys.FAVORITE_COLORS] = colors}}suspend fun clearAllPreferences() {context.dataStore.edit { preferences ->preferences.clear()}}
}
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch@Composable
fun TestPreferencesScreen() {val context = LocalContext.currentval preferencesManager = remember { PreferencesManager(context) }val scope = rememberCoroutineScope()val userName by preferencesManager.userNameFlow.collectAsState(initial = null)val userAge by preferencesManager.userAgeFlow.collectAsState(initial = null)val isPremiumUser by preferencesManager.isPremiumUserFlow.collectAsState(initial = null)val favoriteColors by preferencesManager.favoriteColorsFlow.collectAsState(initial = null)Column(modifier = Modifier.fillMaxSize().padding(16.dp),verticalArrangement = Arrangement.spacedBy(16.dp),horizontalAlignment = Alignment.CenterHorizontally) {Text(text = "User Name: ${userName ?: "Not set"}")Text(text = "User Age: ${userAge ?: "Not set"}")Text(text = "Is Premium User: ${isPremiumUser ?: "Not set"}")Text(text = "Favorite Colors: ${favoriteColors?.joinToString() ?: "Not set"}")Button(onClick = {scope.launch {preferencesManager.saveUserName("John Doe")}}) {Text(text = "Save User Name")}Button(onClick = {scope.launch {preferencesManager.saveUserAge(30)}}) {Text(text = "Save User Age")}Button(onClick = {scope.launch {preferencesManager.saveIsPremiumUser(true)}}) {Text(text = "Save Is Premium User")}Button(onClick = {scope.launch {preferencesManager.saveFavoriteColors(setOf("Red", "Blue", "Green"))}}) {Text(text = "Save Favorite Colors")}Button(onClick = {scope.launch {preferencesManager.batchUpdatePreferences(name = "Jane Smith",age = 25,isPremium = false,colors = setOf("Yellow", "Purple"))}}) {Text(text = "Batch Update Preferences")}Button(onClick = {scope.launch {preferencesManager.clearAllPreferences()}}) {Text(text = "Clear All Preferences")}}
}

分析:TestPreferencesScreen 组件展示了如何在 Compose 中使用 PreferencesManager 来读取和保存偏好设置。通过 collectAsState 方法将 Flow 转换为可观察的状态,当偏好设置发生变化时,界面会自动更新。同时,提供了多个按钮来触发不同的保存和更新操作。

注意:

1 异步操作:DataStore 的所有读写操作都是异步的,需要在协程中进行。在 Compose 中,可以使用rememberCoroutineScope来创建协程作用域。
2 数据迁移:如果从SharedPreferences迁移到 DataStore,需要手动实现数据迁移逻辑。
3 避免在同一进程中为给定文件创建多个DataStore实例:这可能会导致数据不一致或冲突。
4 DataStore的通用类型必须是不可变的:这有助于确保数据的完整性和一致性。
5 不要为同一文件混合使用SingleProcessDataStore和MultiProcessDataStore:这同样可能会导致数据不一致或冲突。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/34841.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML5 drag API实现列表拖拽排序

拖拽API&#xff08;Drag and Drop API&#xff09;是HTML5提供的一组功能&#xff0c;使得在网页上实现拖放操作变得更加简单和强大。这个API允许开发者为网页元素添加拖拽功能&#xff0c;用户可以通过鼠标将元素拖动并放置到指定的目标区域。 事件类型 dragstart&#xff1…

游戏引擎学习第163天

我们可以在资源处理器中使用库 因为我们的资源处理器并不是游戏的一部分&#xff0c;所以它可以使用库。我说过我不介意让它使用库&#xff0c;而我提到这个的原因是&#xff0c;今天我们确实有一个选择——可以使用库。 生成字体位图的两种方式&#xff1a;求助于 Windows 或…

Kafka可视化工具KafkaTool工具的使用

Kafka Tool工具 介绍 使用Kafka的小伙伴&#xff0c;有没有为无法直观地查看 Kafka 的 Topic 里的内容而发过愁呢&#xff1f;下面推荐给大家一款带有可视化页面的Kafka工具&#xff1a;Kafka Tool &#xff08;目前最新版本是 3.0.2&#xff09; 注意&#xff1a;以前叫Kafk…

在Spring Boot项目中接入DeepSeek深度求索,感觉笨笨的呢

文章目录 引言1. 什么是DeepSeek&#xff1f;2. 准备工作2.1 注册DeepSeek账号 3.实战演示3.1 application增加DS配置3.2 编写service3.3 编写controller3.4 编写前端界面chat.html3.5 测试 总结 引言 在当今快速发展的数据驱动时代&#xff0c;企业越来越重视数据的价值。为了…

【数据分析】读取文件

3. 读取指定列 针对只需要读取数据中的某一列或多列的情况&#xff0c;pd.read_csv()函数提供了一个参数&#xff1a;usecols&#xff0c;将包含对应的columns的列表传入该参数即可。 上面&#xff0c;我们学习了读取 "payment" 和 "items_count" 这…

Ubuntu 优化 Vim 指南

Vim 是一款功能强大的文本编辑器&#xff0c;通过合适的配置&#xff0c;可以变成一个接近 IDE 的高效开发工具。本指南提供 最精简、最实用 的 Vim 配置&#xff0c;满足 代码补全、语法高亮、代码格式化、目录管理等常用需求。 1. 必须安装的软件 首先&#xff0c;确保你的系…

信创环境下TOP5甘特图工具对比:从功能到适配性测评

在数字化转型的浪潮中&#xff0c;项目管理的高效与否直接决定了企业能否在激烈的市场竞争中脱颖而出。而甘特图作为项目管理中不可或缺的工具&#xff0c;其重要性不言而喻。尤其是在信创环境日益受到重视的当下&#xff0c;选择一款适配性强、功能完备的甘特图工具&#xff0…

MinIO的预签名直传机制

我们传统使用MinIo做OSS对象存储的应用方式往往都是在后端配置与MinIO的连接和文件上传下载的相关接口&#xff0c;然后我们在前端调用这些接口完成文件的上传下载机制&#xff0c;但是&#xff0c;当并发量过大&#xff0c;频繁访问会对后端的并发往往会对服务器造成极大的压力…

【NLP 38、实践 ⑩ NER 命名实体识别任务 Bert 实现】

去做具体的事&#xff0c;然后稳稳托举自己 —— 25.3.17 数据文件&#xff1a; 通过网盘分享的文件&#xff1a;Ner命名实体识别任务 链接: https://pan.baidu.com/s/1fUiin2um4PCS5i91V9dJFA?pwdyc6u 提取码: yc6u --来自百度网盘超级会员v3的分享 一、配置文件 config.py …

Windows下安装MongoDB 8

在Windows下安装MongoDB&#xff0c;首先需要确定自己的Windows系统版本以及MongoDB社区版所能支持的系统版本。这里使用的是Windows 10操作系统和MongoDB 8.0.4版本。由于MongoDB 6版本之后&#xff0c;不再默认安装Mongo Shell&#xff0c;所以本节分为两部分&#xff1a;安装…

【Node.js入门笔记4---fs 目录操作】

Node.js入门笔记4 Node.js---fs 目录操作一、目录操作1.fs.mkdir()&#xff1a;创建目录。异步&#xff0c;非阻塞。创建单个目录创建多个目录创建目前之前需要确认是否存在&#xff1a; 2. fs.mkdirSync()&#xff1a;用于创建一个新的目录。异步&#xff0c;非阻塞。3.fs.rmd…

DeepSeek-R1思路训练多模态大模型-Vision-R1开源及实现方法思路

刚开始琢磨使用DeepSeek-R1风格训练多模态R1模型&#xff0c;就看到这个工作&#xff0c;本文一起看看&#xff0c;供参考。 先提出问题&#xff0c;仅靠 RL 是否足以激励 MLLM 的推理能力&#xff1f; 结论&#xff1a;不能&#xff0c;因为如果 RL 能有效激励推理能力&#…

Python学习第十八天

Django模型 定义&#xff1a;模型是 Django 中用于定义数据库结构的 Python 类。每个模型类对应数据库中的一张表&#xff0c;类的属性对应表的字段。 作用&#xff1a;通过模型&#xff0c;Django 可以将 Python 代码与数据库表结构关联起来&#xff0c;开发者无需直接编写 S…

总结 HTTP 协议的基本格式, 相关知识以及抓包工具fiddler的使用

目录 1 HTTP是什么 2 HTTP协议格式 3 HTTP请求(Request) 3.1 认识URL 3.2 方法 3.3 认识请求"报头"(header) 3.3.1 Host 3.3.2 Content-Length 3.3.3 Content-Type 3.3.4 User-Agent (简称UA) 3.3.5 Referer 3.3.6 Cookie和Session 4 HTTP响应详解 4.…

【sql靶场】第15、16关-post提交盲注保姆级教程

目录 【sql靶场】第15、16关-post提交盲注保姆级教程 1.知识回顾 ‌GET请求‌ ‌POST请求‌ or与and 2.第十五关 1.布尔盲注的手动注入 1.判断 2.数据库名长度 3.数据库名字符 4.表名数 5.表名长度 6.表名符 7.字段数 8.字段长度 9.字段符 2.布尔盲注的脚本注入…

【C++】 —— 笔试刷题day_6

刷题day_6&#xff0c;继续加油哇&#xff01; 今天这三道题全是高精度算法 一、大数加法 题目链接&#xff1a;大数加法 题目解析与解题思路 OK&#xff0c;这道题题目描述很简单&#xff0c;就是给我们两个字符串形式的数字&#xff0c;让我们计算这两个数字的和 看题目我…

redis终章

1. 缓存(cache) Redis最主要的用途&#xff0c;三个方面1.存储数据&#xff08;内存数据库&#xff09;&#xff1b;2.缓存[redis最常用的场景]&#xff1b;3.消息队列。 缓存(cache)是计算机中的⼀个经典的概念.核⼼思路就是把⼀些常⽤的数据放到触⼿可及(访问速度更快)的地⽅…

Matlab 多输入系统极点配置

1、内容简介 略 Matlab 172-多输入系统极点配置 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 clc close all clear A [-6.5727 1.1902 0 -53.4085;1.1902 -6.5727 0 -53.4085;0.5294 0.5294 0 17.7502;0 0 1 0]; B [1.3797 -0.2498;-0.2498 1.3797;-0.1111 -0.1…

国产编辑器EverEdit - 脚本(解锁文本编辑的无限可能)

1 脚本 1.1 应用场景 脚本是一种功能扩展代码&#xff0c;用于提供一些编辑器通用功能提供不了的功能&#xff0c;帮助用户在特定工作场景下提高工作效率&#xff0c;几乎所有主流的编辑器、IDE都支持脚本。   EverEdit的脚本支持js(语法与javascript类似)、VBScript两种编程…

Flutter 小技巧之通过 MediaQuery 优化 App 性能

许久没更新小技巧系列&#xff0c;温故知新&#xff0c;在两年半前的《 MediaQuery 和 build 优化你不知道的秘密》 我们聊过了在 Flutter 内 MediaQuery 对应 rebuild 机制&#xff0c;由于 MediaQuery 在 MaterialApp 内&#xff0c;并且还是一个 InheritedWidget &#xff0…