This is the 10th day of my participation in Gwen Challenge

Follow the public number anan Android to learn more knowledge

Project Git address:

Github.com/ananananzhu…

Introduce the DataStore

Jetpack DataStore is a data storage solution that allows you to store key-value pairs or typed objects using protocol buffers. DataStore uses Kotlin coroutines and Flows to store data in an asynchronous, consistent transactional manner.

DataStore is used to replace SharePreference, and if your project uses SharePreference, it is recommended that you migrate to DataStore

DataStore provides two implementations, PreferenceDataStore and Proto DataStore

PreferenceDataStore

Storing data in key-value pairs is not type-safe

Proto DataStore

Storing data as custom types ensures type safety

DataStore using

PreferenceDataStore

Rely on

Implementation (" androidx datastore: datastore: 1.0.0 - beta01 ")Copy the code

code

  1. Initialize the DataStore

First we initialize the dataStore in our App,

class App: Application() {
    companion object{
        val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
    }
}
Copy the code

After the val context. dataStore call, we can use the dataStore object globally again

  1. Initialize the key
val EXAMPLE_COUNTER = intPreferencesKey("example_counter")
Copy the code
  1. PreferenceDataStore stores data
dataStore.edit { settings -> val currentCounterValue = settings[EXAMPLE_COUNTER] ? : 0 settings[EXAMPLE_COUNTER] = currentCounterValue + 1 }Copy the code

Each time the code storing data stores data, the data corresponding to EXAMPLE_COUNTER increments by one

  1. PreferenceDataStore retrieves data
val exampleCounterFlow: Flow<Int> = datastore.data.map {preferences -> logEE(preferences[EXAMPLE_COUNTER].tostring ())// Print data preferences[EXAMPLE_COUNTER] ? : 0}Copy the code

ProtoDataStore

The Proto DataStore implementation uses DataStore and protocol buffers to keep typed objects on disk.

The so-called protocol buffer is actually the stream

The integration process for ProtoDataStore is incomplete on the official website, so I found this article to study:

The article entrance

Configure the integration

  1. Integration depends on
Implementation (" androidx datastore: datastore - preferences: 1.0.0 - beta01 ") implementation "Com. Google. Protobuf: protobuf - javalite: 3.10.0"Copy the code
  1. Add Protobuf to Android and Dependencies
Protobuf {/ / set the protoc protoc version {/ / / / downloaded from warehouse protoc here the version number of the need to rely on com. Google. Protobuf: protobuf - javalite: XXX version are the same An artifact = 'com. Google. Protobuf: protoc: 3.10.0'} generateProtoTasks {all (). Each {task - > task. Java builtins {{option "Lite"}}}} / / by default generates $buildDir/generated/source/proto generatedFilesBaseDir = change generated by generatedFilesBaseDir position "$projectDir/src/main" }Copy the code
  1. Add source directory
SourceSets {main {proto {// the default path of proto is SRC /main/proto // srcDir can change the location of proto file srcDir 'SRC /main/proto'}}}Copy the code
  1. Add the Gradle plugin
Id "com. Google. Protobuf" version "0.8.12"Copy the code

Configuration integration is complete.

Code integration

  1. Write a proto file and compile it
  2. Write proto files
syntax = "proto3"; option java_package = "com.ananananzhuo.datastoredemo"; // Must be its own package name option javA_multiple_files = true; message Settings { int32 example_counter = 1; }Copy the code
  1. Write in the compiled Java files SettingsSerializer this file will be moved to the SRC/main/debug/Java/com. Ananananzhuo. Datastoredemo directory
object SettingsSerializer : Serializer<Settings> {
    override val defaultValue: Settings = Settings.getDefaultInstance()

    override suspend fun readFrom(input: InputStream): Settings {
        try {
            return Settings.parseFrom(input)
        } catch (exception: InvalidProtocolBufferException) {
            throw CorruptionException("Cannot read proto.", exception)
        }
    }

    override suspend fun writeTo(
        t: Settings,
        output: OutputStream
    ) = t.writeTo(output)
}

val Context.settingsDataStore: DataStore<Settings> by dataStore(
    fileName = "settings.pb",
    serializer = SettingsSerializer
)
Copy the code
  1. Storing data Storing data must be called in a coroutine
 suspend fun incrementCounter() {
        settingsDataStore.updateData { currentSettings ->
            currentSettings.toBuilder()
                .setExampleCounter(currentSettings.exampleCounter + 1)
                .build()
        }
    }
Copy the code
  1. To get the data
val exampleCounterFlow: Flow < Int > = settingsDataStore. Data. The map {Settings - > logEE (Settings. ExampleCounter. ToString ()) / / get the data and print settings.exampleCounter }Copy the code

Follow the public number anan Android to learn more knowledge