Jetpack DataStore 你总要了解一下吧?

2023-05-16

目录

一、DataStore 介绍

Preferences DataStore 和 Proto DataStore

二、Preferences DataStore

2.1 添加依赖

2.2 使用 Preferences DataStore 存储键值对

2.2.1 创建 DataStore

2.2.1 DataStore 写入数据

2.2.3 DataStore 读取数据

三、Proto DataStore

3.1 定义架构

3.2 创建 Proto DataStore

四、相关链接


一、DataStore 介绍

        DataStore 是 Android Jetpack 中的一个组件,它是一个数据存储的解决方案,跟 SharedPreferences 一样,采用key-value形式存储。

        DataStore 保证原子性,一致性,隔离性,持久性。尤其是,它解决了 SharedPreferences API 的设计缺陷。

        Jetpack DataStore 是经过改进的新版数据存储解决方案,旨在取代 SharedPreferences,让应用能够以异步、事务方式存储数据。

注意:DataStore 比较适合小数据和简单操作,并且无法局部的更新数据。如果你需要支持大型或复杂的数据集、部分更新或引用完整性,请考虑使用 Room 而不是 DataStore。

Preferences DataStore 和 Proto DataStore

  • Preferences DataStore:与SharedPreferences类似,通过键值对存储数据,此实现不需要预定义模式,也不提供类型安全。

  • Proto DataStore:通过Protocol-Buffers定义存储数据类型以及结构,保证类型安全。

        本文重点了解Preferences DataStore。

二、Preferences DataStore

        与SharedPreferences类似,通过键值对存储数据,此实现不需要预定义模式,也不提供类型安全。

2.1 添加依赖

        在你项目的app_module对应的build.gradle中添加如下依赖:

dependencies {
    //Typed DataStore (Typed API surface, such as Proto)
    implementation "androidx.datastore:datastore:1.0.0"
//    //可选 - RxJava2 support
//    implementation "androidx.datastore:datastore-rxjava2:1.0.0"
//    //可选 - RxJava3 support
    implementation "androidx.datastore:datastore-rxjava3:1.0.0"
    
    //Preferences DataStore (SharedPreferences like APIs)
    implementation "androidx.datastore:datastore-preferences:1.0.0"
//    // 可选 - RxJava2 support
//    implementation "androidx.datastore:datastore-preferences-rxjava2:1.0.0"
//    // 可选 - RxJava3 support
    implementation "androidx.datastore:datastore-preferences-rxjava3:1.0.0"
}

2.2 使用 Preferences DataStore 存储键值对

        首先看看 DataStore 源码,DataStore 是一个接口。

package androidx.datastore.core

import kotlinx.coroutines.flow.Flow
import java.io.IOException

/**
 * DataStore数据存储提供了一种安全、持久的方式来存储少量数据,如 preferences 和应用程序状态。
 * 数据存储提供了ACID保证。它是线程安全的,并且不阻塞。特别是,它解决了SharedReferences API的这些设计缺陷:
 * 1. Synchronous API encourages StrictMode violations
 * 2. apply() and commit() have no mechanism of signalling errors
 * 3. apply() will block the UI thread on fsync()
 * 4. Not durable – it can returns state that is not yet persisted
 * 5. No consistency or transactional semantics
 * 6. Throws runtime exception on parsing errors
 * 7. Exposes mutable references to its internal state
 */
public interface DataStore<T> {
    public val data: Flow<T>

    public suspend fun updateData(transform: suspend (t: T) -> T): T
}

以上可以看出 DataStore 是基于 协程 和 Flow 实现的。

  • data 是一个 Flow 对象。

  • updateData() 用于更新对象。

        并且查看 DataStore 的其他相关源码你会发现他们都是基于Kotlin语言开发。Google 对于推 Kotlin 那是相当执着。

2.2.1 创建 DataStore

  • 使用 preferencesDataStore(Kotlin) 创建Datastore<Preferences> 的实例。

  • 如果你使用 RxJava,要使用 RxPreferenceDataStoreBuilder。

        必需的 name 参数是 Preferences DataStore 的名称。

        这里我们使用的是RxJava:

        RxDataStore<Preferences> dataStore =
                new RxPreferenceDataStoreBuilder(this, /*name=*/ "datastore_sc").build();
        //创建使用的key
        Preferences.Key<String> nameKey = PreferencesKeys.stringKey("name");
        Preferences.Key<Integer> ageKey = PreferencesKeys.intKey("age");

        默认路径:/data/data/com.scc.datastorage/files/datastore/datastore_sc.preferences_pb

        这里创建了两个key,分别是 String 类型和 Int 类型。

2.2.1 DataStore 写入数据

    //关于 nameKey 和 ageKey 请看上面代码。
    putString(nameKey, "name-Scc");
    putInteger(ageKey, 25);    
    
    //2022/1/25 功能:存入String类型的数据
    private void putString(Preferences.Key<String> nameKey, String value) {
        dataStore.updateDataAsync(new Function<Preferences, Single<Preferences>>() {
            @Override
            public Single<Preferences> apply(Preferences preferences) throws Throwable {
                MutablePreferences mutablePreferences = preferences.toMutablePreferences();
                mutablePreferences.set(nameKey, value);
                return Single.just(mutablePreferences);
            }
        });
    }
    //2022/1/25 功能:存入Integer类型的数据
    private void putInteger(Preferences.Key<Integer> ageKey, Integer value) {
        dataStore.updateDataAsync(new Function<Preferences, Single<Preferences>>() {
            @Override
            public Single<Preferences> apply(Preferences preferences) throws Throwable {
                MutablePreferences mutablePreferences = preferences.toMutablePreferences();
                mutablePreferences.set(ageKey, value);
                return Single.just(mutablePreferences);
            }
        });
    }

        这里写入的两种类型,这样更加仿版理解和你写成自己的工具类,因为使用 DataStore 比较少实践少就不提供工具类了,以免误导大家。

2.2.3 DataStore 读取数据

    getString(nameKey);
    getInteger(ageKey);
    
    //2022/1/25 功能:获取String类型数据
    private void getString(Preferences.Key<String> nameKey) {
        Log.e("DataStore", nameKey.toString());
        Flowable<String> example = dataStore.data().map(new Function<Preferences, String>() {
            @Override
            public String apply(Preferences preferences) {
                Log.e("DataStore.apply", preferences.get(nameKey));
                return preferences.get(nameKey);
            }
        });
        Log.e("DataStore.Flowable", example.first("default").blockingGet());
    }
    //2022/1/25 功能:获取Integer类型数据
    private void getInteger(Preferences.Key<Integer> ageKey) {
        Log.e("DataStoreKey", ageKey.toString());
        Flowable<Integer> example = dataStore.data().map(new Function<Preferences, Integer>() {
            @Override
            public Integer apply(Preferences preferences) {
                Log.e("DataStore.apply", preferences.get(ageKey).intValue() + "");
                return preferences.get(ageKey);
            }
        });
        Log.e("DataStore.Flowable", example.first(12).blockingGet().toString());
    }

三、Proto DataStore

        通过Protocol-Buffers定义存储数据类型以及结构,保证类型安全。

        Proto DataStore 实现使用 DataStore 和 Protocol-Buffers 将类型化对象持久保存到磁盘。

什么是 Protocol-Buffers?

        Protocol-Buffers是谷歌的语言中立、平台中立、可扩展的机制,用于序列化结构化数据——比如XML,但更小、更快、更简单。您只需定义一次数据的结构化方式,然后就可以使用特殊生成的源代码,轻松地在各种数据流之间以及使用各种语言编写和读取结构化数据。

3.1 定义架构

        Proto DataStore 需要app/src/main/proto/目录中的 proto 文件中的预定义模式。此架构定义了您在 Proto DataStore 中持久保存的对象的类型。

syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.scc.datastorage.proto";
option java_outer_classname = "User";

message User{
  string name = 1;
  int32 age = 2;
}

.proto 文件以包声明开头,这有助于防止不同项目之间的命名冲突。

  • java_multiple_files:可以为每个生成的类生成一个单独的 .java 文件。

  • java_package:指定生成的类应该使用什么 Java 包名称。如果您没有明确指定,它只会匹配包声明给出的包名。

  • java_outer_classname:定义了类名。如果没有设置这个 options ,它将通过将文件名转换为大写驼峰式来生成。例如,默认情况下,“my_proto.proto”将使用“MyProto”作为包装类名称。

定义 message:

  • 可以使用许多标准的简单数据类型可用作字段类型,包括 bool、int32、float、double 和 string。

  • 还可以通过使用其他 message 类型作为字段类型来为你的消息添加进一步的结构。

        每个元素上的 "= 1"、"= 2" 标记标识该字段在二进制编码中使用的唯一 "tag"

        更多关于 的内容可以去官网找找 protobuf 语言指南。

注意:存储对象的类是在编译时从 proto 文件中定义的message生成的。确保你 rebuild 你的项目。

3.2 创建 Proto DataStore

  • 1.定义一个实现 Serializer<T> 的类,其中 T 是 proto 文件中定义的类型。

  • 2.使用 dataStore 创建的属性委托来创建 DataStore<T> 的实例,其中 T 是 proto 文件中定义的类型。

        写到这里 proto 文件中定义的类无法生成,也尝试了很多办法,不知道什么情况。后续步骤可参照官网,其他方法和Preferences DataStore类似。就不占用篇幅了。

四、相关链接

官方文档 DataStore

        个人感觉 DataStore 还没有 SP 和 MMKV 好用,推荐使用 MMKV 毕竟上线好几年了,而且是大厂推出,相对稳定一些,有些个人自己实现了 SP 的功能,但是万一有 Bug 或者突然不继续维护了是不是就尴尬了。

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Jetpack DataStore 你总要了解一下吧? 的相关文章

  • Jetpack的学习

    一 ViewModel ViewModel的一个重要作用就是帮助Activity分担一部分的工作 xff0c 专门存放关于界面相关的数据 只要界面上能看到的数据 xff0c 都应该存放到ViewModel中 另外一个很重要的特性就是当手机屏
  • Jetpack之ViewBinding

    ViewBinding 的作用 xff1a 代替findViewById xff0c 还可以保证空安全和类型安全 基本原理 会为每一个布局xml文件生成一个视图绑定类 xff0c 类名称是布局文件名转化为UpperCamelCase 43
  • Jetpack-Compose-自定义绘制

    上节课我们简单的利用了一下自定义裁剪和自定义就能玩出如下简单案例 效果不错 这节课咋们来看看Compose自定义绘制能不能花里胡哨 一 Compose自定义 自定义 一个应用的可创造性往往离不开人们的千奇百怪想象和用户变化万千的需求 自定义
  • JetPack-Compose - Flutter 动态UI?

    一 Flutter 初遇 2018 06月左右入坑Flutter 于是拿出美团和痘印等好看的界面感受了一波Flutter UI和绘制等写了三天的Demo也感受到了Flutter强大 当时匆匆忙忙就写了相关Demo上传了Github 不知不觉
  • Jetpack Compose 从入门到入门(四)

    本篇开始介绍Jetpack Compose 中常用的组件 有一部分之前的文章中也出现过 xff0c 今天详细说明一下 1 Text 日常最常用的应该就是显示文字 xff0c 所以有必要说一下Text控件 首先源码如下 xff1a span
  • Linux中如何查Jetson Nano中jetpack的版本

    命令 xff1a cat etc nv tegra release 如下图所示 xff0c 输入的内容为 R32 release REVISION 5 1 GCID 26202423 BOARD t210ref EABI aarch64 D
  • Jetpack刷机TX2(大坑)【记录问题】

    Jetpack刷机TX2 xff08 大坑 xff09 1 Jetson TX2 刷机时遇到的坑 xff1a https blog csdn net zshluckydogs article details 79855631 xff01 x
  • Jetson tx2 安装jetpack_3.3手动安装cuda9.0,cudnn7.1

    1 刷机前的准备 xff08 写在前面的话 xff09 装有Ubuntu16 04或者Ubuntu18 04的电脑 xff0c 这里说的电脑可以是台式机也可以是笔记本与TX2区分开来 xff08 电脑是16 04或者18 04无所谓 xff
  • Jetpack练手(04):Lifecycle

    文章目录 一 搭建布局二 非 Lifecycle 实现三 Lifecycle 实现四 Demo 效果 一 搭建布局 新建 LifecycleDemo 工程实现 界面停留时间计时 xff0c 在 activity main xml 搭建简单布
  • Android DataBinding的基本使用

    5 DataBinding https developer android com topic libraries data binding custom conversions 数据绑定库是一种支持库 借助该库 您可以使用声明性格式 而非
  • 不贴代码能说明白Jetpack LiveData原理吗(一)

    LifecycleOwner如何提供周期生命周期的变化 LifecycleObserver如何得知生命周期的变化 LiveData的背后隐藏了多少不为人知的秘密 这一切都要从观察者模式说起 起源 何为观察者模式 在代码中最直接的表现就是在事
  • Jetpack学习之Lifecycle

    Jetpack是Google为了解决Android架构问题而引入的 Google官方说的说法 Jetpack是一套库 工具和指南 可以帮助开发者更轻松地编写应用程序 Jetpack中的组件可以帮助开发者遵循最佳做法 摆脱编写样板代码的工作并
  • Jetpack-Compose之一基础使用

    一 命令式UI和申明式UI 如果之前有了解或者使用果Flutter 应该会对命令式UI这种架构不陌生 目前申明式UI确实是很火包含Flutter SwiftUI JetpackCompose都使用了该种方式 2021年7月底 Google
  • Nvidia TX2 刷机教程 JetPack-L4T-3.0-linux-x64.run

    前言 本教程特别针对刷机被墙的朋友 如果没有被墙 其实按照官方文档一步一步操作就行 这期间我参考了特别多的网页 也去nvidia官方论坛问过 其实截止到2019年2月16日 jetpack3 3 是可以很轻松的被装上的 主要是3 0被墙 而
  • 一文带你了解ViewModel

    Lifecycle库可以有效避免内存泄漏和解决常见的Android生命周期难题 1 引言 ViewModel属于lifecycle 生命周期感知型组件 中的一员 通常与LiveData DataBinding一起使用 它们是MVVM架构的重
  • Jetpack Compose多平台用于Android和IOS

    JetBrains和外部开源贡献者已经努力工作了几年时间来开发Compose Multiplatform 并最近发布了适用于iOS的Alpha版本 自然地 我们对其功能进行了测试 并决定通过使用该框架在iOS上运行我们的Dribbble复制
  • Android DataStore 使用详解

    转载请标明出处 http blog csdn net zhaoyanjun6 article details 127358235 本文出自 赵彦军的博客 文章目录 概述 使用 DataStore 本地数据 查看DataStore 文件 Ke
  • 在单个 RDS 文件中保存多个变量

    我想将变量列表传递给 saveRDS 以保存它们的值 但它会保存它们的名称 variables lt c A B C saveRDS variables file R 它保存单个向量 变量 我也尝试过 save variables file
  • 当需要 getter 和 setter 方法时如何在 Python 模块之间共享变量

    如果我需要这些变量具有 setter 和 getter 方法 如何在 Python 项目的不同模块之间共享变量 我需要 setter getter 方法的原因是 在获取和设置变量时 我需要与将这些变量存储为环境变量的代码向后兼容 所以我也需
  • 在 GAE 中实施独特的约束

    我正在尝试 Google App Engine Java 但是缺乏独特的约束使事情变得困难 我已经通过这篇文章 https stackoverflow com questions 2626978 unique constraint at d

随机推荐

  • R语言数据类型转化

    R语言数据类型转化 转自 xff1a http www wangluqing com 2014 09 10 r share34 有时候 xff0c 对于一些问题 xff0c 需要进行数据类型之间的转换 R提供了基本类型转换函数以解决数据类型
  • ubuntu20.04安装中文输入法

    虽然搜狗的官网已经宣传说已经支持2004 2010 xff0c 但是支持的并不完美 xff0c 闪退 xff0c 打不出字各种问题不断 xff0c 所以本文带领大家安装几款能够正常使用的中文输入法 但是正在我要发这篇博客的时候 xff0c
  • R语言做柱状图

    R语言做柱状图 转自 xff1a http www phperz com article 16 0102 180120 html 条形图代表在与条成比例的变量的值的长度矩形条数据 R使用函数barplot 来创建柱状图 R能够绘制柱状图垂直
  • R语言 PCA(主成分分析)

    R语言 PCA 转自 xff1a http www cnblogs com longzhongren p 4300593 html 1 关键点 综述 xff1a 主成分分析 因子分析 典型相关分析 xff0c 三种方法的共同点主要是用来对数
  • 使用Pandas对数据进行筛选和排序

    使用Pandas对数据进行筛选和排序 转自 xff1a http bluewhale cc 2016 08 06 use pandas filter and sort html 筛选和排序是Excel中使用频率最多的功能 xff0c 通过这
  • linux 下安装blat软件

    linux 下安装blat软件 blat是一款很经典的比对工具 xff0c 与blast相比 xff0c 具有速度快 共线性输出比对结果等优点 但是 xff0c blat源码包里面的README文件写得很不清楚 xff0c 这里 xff0c
  • 基于统计的压缩算法:游程编码

    原网址 xff1a http www cnblogs com xudong bupt p 3761417 html 基于统计的压缩算法 xff1a 游程编码 1 游程编码概念 游程编码又称 运行长度编码 或 行程编码 xff0c 是一种统计
  • BWT (Burrows–Wheeler_transform)数据转换算法

    原网址 xff1a https blog csdn net luanzheng 365 article details 78575429 BWT Burrows Wheeler transform 数据转换算法 1 什么是BWT 压缩技术主
  • pip使用豆瓣的镜像源

    抄自 xff1a https www cnblogs com ZhangRuoXu p 6370107 html pip使用豆瓣的镜像源 豆瓣镜像地址 xff1a https pypi douban com simple 虽然用easy i
  • PyVCF

    抄自 xff1a https www cnblogs com nkwy2012 p 9204088 html vcf文件的全称是variant call file xff0c 即突变识别文件 xff0c 它是基因组工作流程中产生的一种文件
  • 【Kotlin 初学者】扩展-享受编程

    作者简介 xff1a CSDN博客专家 华为云 云享专家认证 系列专栏 xff1a Kotlin 初学者 学习交流 xff1a 三人行必有我师焉 xff1b 择其善者而从之 xff0c 其不善者而改之 目录 一 介绍 二 扩展函数 2 1
  • 【Kotlin 初学者】函数式编程

    作者简介 xff1a CSDN博客专家 华为云 云享专家认证 系列专栏 xff1a Kotlin 初学者 五星好评 xff1a 左侧点一下 网页端 xff0c 移动端 xff1a https bbs csdn net topics 6039
  • centos8.5 更新失败

    今天使用yum makecache的时候出现了Error Failed to download metadata for repo 39 base 39 Cannot download repomd xml Cannot download
  • 【Kotlin 初学者】Java和Kotlin互操作

    作者简介 xff1a CSDN博客专家 华为云 云享专家认证 系列专栏 xff1a Kotlin 初学者 五星好评 xff1a 左侧点一下 网页端 xff0c 移动端 xff1a https bbs csdn net topics 6039
  • Kotlin 基础知识汇总(知识与实践相结合)

    2个月的时间总算把 Kotlin 的基础知识写完了 xff0c 下面咱们看看具体内容 xff1a 学习 Kotlin 的必要性 Kotlin 初学者 为什么要学Kotlin Kotlin 初学者 打牢基础的重要性 运行环境 Kotlin 初
  • HashMap的产生与原理

    一 HashMap的诞生 1 1 数组 数组 xff1a 一片物理上连续的大小确定的储存空间 好处 xff1a 根据下标快速的查找和修改里面的内容 缺点 xff1a 大小确定 xff0c 无法修改 添加新的元素或者删除元素比较麻烦 数组的静
  • Android 数据存储(一)-文件存储

    目录 一 数据存储概念 二 应用程序专属文件存储 2 1 访问持久文件 2 2 将数据存储到文件 2 3 从文件中读取数据 2 4 查看文件列表 2 5 删除文件 三 缓存文件 cache目录下 3 1 创建缓存文件 3 2 删除文件 四
  • 回顾2021,展望2022 | 年终总结

    你付出多少努力 xff0c 就必有多少收获 一 回顾 2021 2021 年输出109篇文章 xff0c 收获 xff1a 博客专家认证 Android领域新星创作者认证 博客之星Top50 同时也在问答模块解决了部分小伙伴的问题 xff0
  • Android 数据存储(二)-SP VS DataStore VS MMKV

    一 SharedPreferences 不同于文件的存储方式 xff0c 如果要保存的键值集合相对较小 xff0c 则应使用SharedReferences API SharedReferences对象指向一个包含键值对的文件 xff0c
  • Jetpack DataStore 你总要了解一下吧?

    目录 一 DataStore 介绍 Preferences DataStore 和 Proto DataStore 二 Preferences DataStore 2 1 添加依赖 2 2 使用 Preferences DataStore