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)