datastore java_Android 使用DataStore存储数据
1 添加依赖
2 在 main 文件夹下创建 .proto 文件
3 编写 Serializer
4 编写基础存储工具类
5 举例使用
** 5.1 创建 DataStore 存储工具子类
** 5.2 基本使用
6 混淆
1 添加依赖
implementation "androidx.datastore:datastore:1.0.0-alpha06"
implementation "androidx.datastore:datastore-preferences:1.0.0-alpha06"
implementation "com.google.protobuf:protobuf-java:3.15.0"
2 在 main 文件夹下创建 .proto文件
.proto
syntax = "proto3";
option java_package = "com.afra55.xxx.ds.event";
option java_multiple_files = true;
message MessageEvent {
int32 type = 1;
string message = 2;
}
根据不同的存储需求来实现不同的 proto 文件,然后进行编译, java_package 是生成文件的路径
protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/ds.proto
例如当在 proto 文件夹下:
protoc -I=. --java_out=../java ./ds.proto
许多标准的简单数据类型都可以作为字段类型,包括bool,int32,float,double,和string。
ds
3 编写 Serializer
object MessageEventSerializer :Serializer{
override val defaultValue: MessageEvent
get() = MessageEvent.getDefaultInstance()
override fun readFrom(input: InputStream): MessageEvent {
try {
return MessageEvent.parseFrom(input)
} catch (e: Exception) {
throw CorruptionException("Cannot read proto.", e)
}
}
override fun writeTo(t: MessageEvent, output: OutputStream) {
t.writeTo(output)
}
}
4 编写基础存储工具类
import androidx.datastore.core.DataStore
import androidx.datastore.createDataStore
import androidx.datastore.preferences.core.*
import androidx.datastore.preferences.createDataStore
import androidx.datastore.createDataStore
import com.afra55.thunderomadtestapplication.AppApplication
import com.afra55.thunderomadtestapplication.ds.event.MessageEvent
import com.afra55.thunderomadtestapplication.toJsonString
import com.afra55.thunderomadtestapplication.toObject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlin.reflect.KClass
/**
* @author Afra55
* @date 2/18/21
* A smile is the best business card.
*
* 需要添加混淆:
-keepclassmembers class * extends androidx.datastore.preferences.protobuf.GeneratedMessageLite {
;
}
*/
open class DataStoreBase(name: String) {
val dataStore: DataStore? by lazy {
AppApplication.context?.createDataStore(name)
}
val messageEventDataStore: DataStore? by lazy {
AppApplication.context?.createDataStore(
fileName = name,
serializer = MessageEventSerializer
)
}
suspend fun getString(key: String, defaultValue:String? = null):String? {
return dataStore?.data?.map { preferences ->
preferences[stringPreferencesKey(key)] ?: defaultValue
}?.first()
}
suspend fun getInt(key: String, defaultValue:Int? = null): Int? {
return dataStore?.data?.map { preferences ->
preferences[intPreferencesKey(key)] ?: defaultValue
}?.first()
}
suspend fun getDouble(key: String, defaultValue:Double? = null): Double? {
return dataStore?.data?.map { preferences ->
preferences[doublePreferencesKey(key)] ?: defaultValue
}?.first()
}
suspend fun getBoolean(key: String, defaultValue:Boolean? = null): Boolean? {
return dataStore?.data?.map { preferences ->
preferences[booleanPreferencesKey(key)] ?: defaultValue
}?.first()
}
suspend fun getFloat(key: String, defaultValue:Float? = null): Float? {
return dataStore?.data?.map { preferences ->
preferences[floatPreferencesKey(key)] ?: defaultValue
}?.first()
}
suspend fun getLong(key: String, defaultValue:Long? = null): Long? {
return dataStore?.data?.map { preferences ->
preferences[longPreferencesKey(key)] ?: defaultValue
}?.first()
}
suspend fun getStringSet(key: String, defaultValue:Set? = null): Set? {
return dataStore?.data?.map { preferences ->
preferences[stringSetPreferencesKey(key)] ?: defaultValue
}?.first()
}
suspend fun getObject(key: String, clazz: Class, defaultValue:T? = null): T? {
return dataStore?.data?.map { preferences ->
val a = preferences[stringPreferencesKey(key)]
if (a != null) {
a.toObject(clazz) as T
} else {
defaultValue
}
}?.first()
}
suspend fun get(key: String, clazz: KClass, defaultValue: T? = null): T? {
val pKey = when (clazz) {
String::class -> {
stringPreferencesKey(key)
}
Int::class -> {
intPreferencesKey(key)
}
Double::class -> {
doublePreferencesKey(key)
}
Boolean::class -> {
booleanPreferencesKey(key)
}
Float::class -> {
floatPreferencesKey(key)
}
Long::class -> {
longPreferencesKey(key)
}
Set::class -> {
stringSetPreferencesKey(key)
}
else -> {
null
}
}
return dataStore?.data?.map { preferences ->
if (pKey != null) {
(preferences[pKey] as? T) ?: defaultValue
} else {
val a = preferences[stringPreferencesKey(key)]
if (a != null) {
a.toObject(clazz::class.java) as T
} else {
defaultValue
}
}
}?.first()
}
suspend fun put(key: String, value: Any) {
when (value::class) {
String::class -> {
dataStore?.edit { settings ->
settings[stringPreferencesKey(key)] = value as String
}
}
Int::class -> {
dataStore?.edit { settings ->
settings[intPreferencesKey(key)] = value as Int
}
}
Double::class -> {
dataStore?.edit { settings ->
settings[doublePreferencesKey(key)] = value as Double
}
}
Boolean::class -> {
dataStore?.edit { settings ->
settings[booleanPreferencesKey(key)] = value as Boolean
}
}
Float::class -> {
dataStore?.edit { settings ->
settings[floatPreferencesKey(key)] = value as Float
}
}
Long::class -> {
dataStore?.edit { settings ->
settings[longPreferencesKey(key)] = value as Long
}
}
Set::class -> {
dataStore?.edit { settings ->
settings[stringSetPreferencesKey(key)] = value as Set
}
}
else -> {
dataStore?.edit { settings ->
settings[stringPreferencesKey(key)] = value.toJsonString()
}
}
}
}
suspend fun getMessageEventType():Int? {
return messageEventDataStore?.data?.map {
it.type
}?.first()
}
suspend fun getMessageEventData():String? {
return messageEventDataStore?.data?.map {
it.message
}?.first()
}
suspend fun getMessageEvent():MessageEvent? {
return messageEventDataStore?.data?.map {
it
}?.first()
}
suspend fun putMessageEvent(message:String) {
messageEventDataStore?.updateData {
it.toBuilder()
.setType(it.type)
.setMessage(message)
.build()
}
}
suspend fun putMessageEvent(type:Int) {
messageEventDataStore?.updateData {
it.toBuilder()
.setType(type)
.setMessage(it.message)
.build()
}
}
suspend fun putMessageEvent(type:Int, message:String) {
messageEventDataStore?.updateData {
it.toBuilder()
.setType(type)
.setMessage(message)
.build()
}
}
}
5 举例使用
5.1 创建 DataStore 存储工具子类
object IPDataStore :DataStoreBase("ip"){
}
5.2 基本使用
lifecycleScope.launch {
Log.i("ip", IPDataStore.getString("ip")?:"null")
Log.i("message_event", IPDataStore.getMessageEventType().toString())
Log.i("message_event", IPDataStore.getMessageEventData().toString())
val r = withContext(Dispatchers.IO){
try {
runHttp("http://ip-api.com/json")
} catch (e: Exception) {
e.printStackTrace()
}
}
if (r is String) {
IPDataStore.put("ip", r)
IPDataStore.putMessageEvent(12, r)
IPDataStore.getString("ip")?.let {
Log.i("ip", it?:"null")
}
}
Log.i("message_event", IPDataStore.getMessageEventType().toString())
Log.i("message_event", IPDataStore.getMessageEventData().toString())
IPDataStore.getMessageEvent()?.let {
Log.i("message_event", it.toString())
}
Log.i("ip", "获取完成")
}
var client = OkHttpClient()
fun runHttp(url: String): String? {
val request: Request = Request.Builder()
.url(url)
.build()
client.newCall(request).execute().use { response -> return response.body!!.string() }
}
6 混淆
-keepclassmembers class * extends androidx.datastore.preferences.protobuf.GeneratedMessageLite {
;
}
datastore java_Android 使用DataStore存储数据相关推荐
- 2021年大数据HBase(十三):HBase读取和存储数据的流程
全网最详细的大数据HBase文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 HBase读取和存储数据的流程 一.HBase读取数据的流程 ...
- .pgr照片文件解析,C++与Java存储数据差别大小端模式
一..pgr是什么? .pgr文件是二进制的图像文件,可以用普通的文本文件打开,或者查看十六进制的文本信息: 读取需要了解~~~非常重要 !!! 基本数据类型的大小端存储模式 表头Header 详细信 ...
- string生成固定长度的哈希_Redis 选择Hash还是String 存储数据?
点击上方"Java之间",选择"置顶或者星标" 你关注的就是我关心的! 作者:goodspeed 微信公众号:四月(ID:hiiiapril) 在stackov ...
- 在python中使用json格式存储数据
在python中使用json格式存储数据 代码如下: import jsonlist1 = [{'A': [1, 2, 3, 4, 5, 6], 'B': [3, 4, 5, 6, 7]},{'C': ...
- android studio数据库存储数据,如何使用API 23在android studio中的数据库中存储数据?...
大多数时候我不会发布任何内容,因为我可以在其他帖子中找到我需要的所有内容,但是现在我已经有几天了,您如何在数据库中存储任何内容?这是我的Java代码如何使用API 23在android studi ...
- 关于外部存储器件对存储数据的管理。
一引子 :需要大量存储数据时,一般都不会使用单片机内部存储资源(单片机内部的eerom或者flash模拟eeprom只适合存储少量的数据).一般是通过I2C/SPI接口外部扩展eeprom或者flas ...
- 使用嵌入式关系型SQLite数据库存储数据
除了可以使用文件或SharedPreferences存储数据,还可以选择使用SQLite数据库存储数据. 在Android平台上,集成了一个嵌入式关系型数据库-SQLite,SQLite3支持 NUL ...
- android的数据存储方式有哪几种方式,Android存储数据的5种方式
第一种:SharedPreferences 1.使用键值对的方式存储数据 2.通常用于:保存用户的偏好设置.选择是否保存密码.记录文档阅读的位置等 3.实现方式(写入): a).获取SharedPre ...
- 前端 在浏览器端存储数据
在前端中存储数据大致有三种模式: 1:cookie:但是cookie的空间只有4k,所以很少使用: 2:sessionStorage: 是在本地存储数据,其空间有最多可以达到5M,但是生命周期是浏览器 ...
- 【转】Android使用嵌入式关系型SQLite数据库存储数据【学习记录】
为什么80%的码农都做不了架构师?>>> 除了可以使用文件或SharedPreferences存储数据,还可以选择使用SQLite数据库存储数据. 在Android平台上,集成 ...
最新文章
- PTA基础编程题目集-6-9 统计个位数字
- 查找局域网中的DHCP服务器
- 集群(三)——haproxy+nginx搭建web集群
- JS过滤表单数据中的特殊字符
- JavaScript操作大全整理(思维导图三--函数基础)
- java grpc 客户端处理 go 服务端多返回值_grpc基础实践(二)
- 【Asp.Net】C#中checked关键字的应用
- 软件测试 学习之路 计算机基础
- 今晚直播丨国产数据库入门:openGauss数据库的基本管理和SQL语句入门
- 深度学习 --- 受限玻尔兹曼机RBM(MCMC接受率详解)
- 美化下拉框select箭头部分(不彻底)
- 一些抄来的冷知识...
- 【嵌入式】牧马人G3 电子竞技鼠标拆解分析
- 项目引入船讯网海图插件
- CentOS6.5挂载大于2TB的磁盘使用parted和GPT类型
- Idea如何配置svn或集成svn。
- linux里shell的心得,Shell学习心得(一):变量
- 百度云主机使用WordPress建站ideashare.club过程总结与那些坑
- 单片机的电子电路基本知识
- nullspace matlab,用numpy计算零空间的有理基
热门文章
- su 无法切换账户(密码正确)一直提示Authentication failure(认证失败)
- 利用laravel框架创建todos
- 英雄联盟商城登录界面
- 京东商城发现了一枚Bug
- 用python做探索性因子分析(Exploratory Factor Analysis,EFA)全代码
- 优质短信api接口具备的特点
- face_recognition库的使用
- 大数据平台以及一些核心组件介绍
- 生态 | 国内数据库领域权威学术会议NDBC 2020成功举办,人大金仓受邀参会并发表主题演讲...
- 计算机读不出光盘,光驱读不出光盘,小编教你电脑光盘不能被识别怎么解决