当前位置: 首页 > news >正文

DataStore存储数据+加上加密

如果没有使用SP来存储数据,而是用datastore的话

但是datastore存储是个文件,所以我们需要再加密。

先展示没有加密的存储方式,然后再结合上一节的加密,再将存储的数据进行加密

使用datastore存储数据

添加依赖库

implementation "androidx.datastore:datastore-preferences:1.0.0"
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2'

定义数据类型

定义data class,添加 @Serializable 标签

@Serializable
data class UserSettings(val username: String? = null,val password: String? = null
)

定义Serializer

这里先展示没有加密的的序列化

存储的时候,将实例值转换成json string,再转换成bytearray写出到输出流,就可以保存到datastore的文件上了

读取的时候,从输入流中读取转成json string, 再通过json解析成 UserSetting实例

//继承datastore的Serializer,类型是我们定义的UserSettings
@RequiresApi(Build.VERSION_CODES.M)
class UserSettingsSerializer() : Serializer<UserSettings> {override val defaultValue: UserSettingsget() = UserSettings()override suspend fun readFrom(input: InputStream): UserSettings {//将输入端的内容先转换成string//再将string通过json的解析再转换成UserSettingsreturn try {Json.decodeFromString(deserializer = UserSettings.serializer(),string = inputStreamToByteArray(input).decodeToString()//decryptedBytes.decodeToString())} catch(e: SerializationException) {e.printStackTrace()defaultValue}}private fun inputStreamToByteArray(inputStream: InputStream): ByteArray {val dataInputStream = DataInputStream(inputStream)val byteArrayOutputStream = ByteArrayOutputStream()val buffer = ByteArray(1024)var length: Intwhile ((dataInputStream.read(buffer).also { length = it }) != -1) {byteArrayOutputStream.write(buffer, 0, length)}return byteArrayOutputStream.toByteArray()}override suspend fun writeTo(t: UserSettings, output: OutputStream) {//把值为t的UserSettings,通过序列化转换成json string,再写出到输出流val bytes =Json.encodeToString(serializer=UserSettings.serializer(), value = t).encodeToByteArray()output.write(bytes)}
}

初始化datastroe

datastore的文件名,传入我们前面定义的普通的序列化器UserSettingsSerializer,

定义的是Context.dataStore,这在Context中都可以访问到datastore。例如activity中就可以直接使用datastore

 private val Context.dataStore by dataStore(fileName = "user-settings.json",serializer = UserSettingsSerializer())

跟新数据到datastore

                                dataStore.updateData {UserSettings(username = username,password = password)}

读取数据

settings = dataStore.data.first()

直接就可以读取到 UserSetting类型的数据

查看文件

从data-data-packagename下可以看到文件

直接可以看到JSON格式的内容,这样就不是很安全,所以,存储到datastore中的内容需要加密

这个就连接上一篇中的AES加密

https://blog.csdn.net/github_35581409/article/details/142894715

只要对UserSettingsSerializer进行改造,在写入的时候,把JSON string进行加密

在读取的时候,先对string解密,然后再JSON解析

加密改造

添加加密管理

class UserSettingsSerializer(private val cryptoManager: CryptoManager //添加加密管理
) : Serializer<UserSettings>

写入

写入的时候,将实例值通过json编码,然后转换成byte。然后再通过cryptoManager进行加密,再写入输出流,输出流会把加密后的数据存储到datastore的文件中

    override suspend fun writeTo(t: UserSettings, output: OutputStream) {cryptoManager.encrypt(bytes = Json.encodeToString(serializer = UserSettings.serializer(),value = t).encodeToByteArray(),outputStream = output)
//        val bytes =Json.encodeToString(serializer=UserSettings.serializer(), value = t)
//            .encodeToByteArray()
//        output.write(bytes)}

读取

把输入流中的内容,先进行解码,解码后的byte,在通过json组装成实例

    override suspend fun readFrom(input: InputStream): UserSettings {val decryptedBytes = cryptoManager.decrypt(input) //将输入流进行加密,生成加密后的bytesreturn try {Json.decodeFromString(deserializer = UserSettings.serializer(),
//                string = inputStreamToByteArray(input).decodeToString()decryptedBytes.decodeToString())} catch(e: SerializationException) {e.printStackTrace()defaultValue}}

在datastore初始化的时候,补上加密管理器

   private val Context.dataStore by dataStore(fileName = "user-settings.json",serializer =UserSettingsSerializer(CryptoManager()))

再运行看看,加解密显示没有问题,

文件内容也变成了加密的了


http://www.mrgr.cn/news/49442.html

相关文章:

  • C++的类和动态内存分配(深拷贝与浅拷贝)并实现自己的string类
  • vue3之 shallowRef、markRaw
  • [Linux] 软硬链接
  • 7.2-I2C的DMA中断
  • RAII - 安卓中的智能指针
  • 如何有效参与机器人顶会?——周易教授PRE-IROS 2024分享
  • GS-LRM: Large Reconstruction Model for 3D Gaussian Splatting 论文解读
  • 性能测试-JMeter(3)
  • 深度解读 JDK 8、JDK 11、JDK 17 和 JDK 21 的区别
  • CountUp.js 实现数字增长动画 Vue
  • 苏姿丰发布AMD最强AI芯片|苹果质疑大语言模型根本无法进行逻辑推理|Kimi的商业化困局|杰弗里·辛顿:“图灵诺奖双得主”、“AI教父”,至高荣誉加身
  • RabbitMQ 高级特性——死信队列
  • MySQL从入门到跑路
  • AI/LLM 大模型入门指南相关的命令行脚本
  • OpenCV系列教程四:特征检测与特征匹配,图像查找、对齐和拼接
  • Yocto - 使用Yocto开发嵌入式Linux系统_09 深入了解BitBake元数据
  • 用SAM2和Cutie模型目标追踪
  • 程序地址空间 -- 详解
  • Download Vmware Fusion (free for person)
  • Dev-Cpp 5.11 安装教程【保姆级】