Até agora, compartilhamos como usar o DataStore com Protos ou Preferences. Nos bastidores, as duas versões do DataStore usam Protos para serializar os dados. Você também pode usar o DataStore com classes de dados personalizadas por meio da serialização do Kotlin. Isso pode ajudar a reduzir o código boilerplate sem a necessidade de aprender ou depender da biblioteca Protobuf e, ainda assim, fornecer um esquema para os dados.
As classes de dados do Kotlin são ótimas para uso com o DataStore porque funcionam perfeitamente com a serialização do Kotlin. O DataStore depende de equals e hashCode, que são gerados automaticamente para as classes de dados. As classes de dados também geram funções toString e copy, que são úteis para depurar e atualizar dados.
equals
hashCode
toString
copy
/* Copyright 2021 Google LLC. SPDX-License-Identifier: Apache-2.0 */ data class UserPreferences( val showCompleted: Boolean, val sortOrder: SortOrder )
É muito importante assegurar que a classe de dados seja imutável, já que o DataStore não é compatível com tipos mutáveis. O uso de tipos mutáveis com o DataStore resultará em bugs e disputas difíceis de detectar. As classes de dados não são necessariamente imutáveis.
Vars são mutáveis, por isso você deve usar vals: /* Copyright 2021 Google LLC. SPDX-License-Identifier: Apache-2.0 */ data class MyData( - var num: Int + val num: Int ) - myObj.num = 5 // Fails to compile when num is val + val newObj = myObj.copy(num = 5)
/* Copyright 2021 Google LLC. SPDX-License-Identifier: Apache-2.0 */ data class MyData( - var num: Int + val num: Int ) - myObj.num = 5 // Fails to compile when num is val + val newObj = myObj.copy(num = 5)
Arrays são mutáveis, por isso não devem ser expostas. /* Copyright 2021 Google LLC. SPDX-License-Identifier: Apache-2.0 */ data class MyData( - var num: IntArray ) - myObj.num = 5 // This would mutate your object
/* Copyright 2021 Google LLC. SPDX-License-Identifier: Apache-2.0 */ data class MyData( - var num: IntArray ) - myObj.num = 5 // This would mutate your object
Mesmo que um List somente leitura seja usado como um membro da classe de dados, ele ainda é mutável. Em vez disso, considere usar coleções imutáveis/persistentes:
/* Copyright 2021 Google LLC. SPDX-License-Identifier: Apache-2.0 */ data class MyData( - val nums: List + val nums: PersistentList ) - val myInts = mutableListOf(1, 2, 3, 4) - val myObj = MyData(myInts) - myInts.add(5) // Fails to compile with PersistentList, but mutates with List + val newData = myObj.copy( + nums = myObj.nums.mutate { it += 5 } // Mutate returns a new PersistentList + )
O uso de tipos mutáveis como membros da classe de dados a torna mutável. Em vez disso, garanta que todos os membros sejam tipos imutáveis.
/* Copyright 2021 Google LLC. SPDX-License-Identifier: Apache-2.0 */ data class MyData( - val mutableType: MutableType ) - val myType = MutableType() - val myObj = MyData(myType) - myType.mutate()
A serialização do Kotlin dá suporte a vários formatos, incluindo JSON e buffers de protocolo. Aqui, usarei o JSON porque ele é muito comum, fácil de usar e armazenado em texto não criptografado, o que facilita a depuração. Protobuf também é uma boa opção, porque é menor, mais rápido e compatível com protobuf-lite.
A fim de ler e gravar a classe de dados em JSON usando a serialização do Kotlin, você precisa anotar a classe de dados com @Serializable e usar Json.decodeFromString<YourType>(string) e Json.encodeToString(data). Este é um exemplo com UserPreferences:
@Serializable
Json.decodeFromString<YourType>(string)
Json.encodeToString(data)
UserPreferences
/* Copyright 2021 Google LLC. SPDX-License-Identifier: Apache-2.0 */ @Serializable data class UserPreferences( val showCompleted: Boolean = false, val sortOrder: SortOrder = SortOrder.None ) object UserPreferencesSerializer : Serializer { override val defaultValue = UserPreferences() override suspend fun readFrom(input: InputStream): UserPreferences { try { return Json.decodeFromString( UserPreferences.serializer(), input.readBytes().decodeToString()) } catch (serialization: SerializationException) { throw CorruptionException("Unable to read UserPrefs", serialization) } } override suspend fun writeTo(t: UserPreferences, output: OutputStream) { output.write(Json.encodeToString(UserPreferences.serializer(), t).encodeToByteArray()) } }
⚠ Parcelables não são seguros para uso com o DataStore porque o formato de dados pode mudar entre as versões do Android.
Transmita o serializador criado para o DataStore ao construí-lo: /* Copyright 2021 Google LLC. SPDX-License-Identifier: Apache-2.0 */ val Context.dataStore by dataStore("my_file.json", serializer = UserPreferencesSerializer)
/* Copyright 2021 Google LLC. SPDX-License-Identifier: Apache-2.0 */ val Context.dataStore by dataStore("my_file.json", serializer = UserPreferencesSerializer)
A leitura de dados é semelhante à de protos: /* Copyright 2021 Google LLC. SPDX-License-Identifier: Apache-2.0 */ suspend fun getShowCompleted(): Boolean { context.dataStore.data.first().showCompleted }
/* Copyright 2021 Google LLC. SPDX-License-Identifier: Apache-2.0 */ suspend fun getShowCompleted(): Boolean { context.dataStore.data.first().showCompleted }
Você pode usar a função .copy() gerada para atualizar dados: /* Copyright 2021 Google LLC. SPDX-License-Identifier: Apache-2.0 */ suspend fun setShowCompleted(newShowCompleted: Boolean) { // This will leave the sortOrder value untouched: context.dataStore.updateData { it.copy(newShowCompleted = showCompleted) } }
.copy()
/* Copyright 2021 Google LLC. SPDX-License-Identifier: Apache-2.0 */ suspend fun setShowCompleted(newShowCompleted: Boolean) { // This will leave the sortOrder value untouched: context.dataStore.updateData { it.copy(newShowCompleted = showCompleted) } }
O uso do DataStore com a serialização do Kotlin e as classes de dados pode reduzir o código boilerplate e ajudar a simplificar o código. Mas é preciso ter cuidado para não introduzir bugs devido à mutabilidade. Tudo o que você precisa fazer é definir a classe de dados e implementar o serializador. Experimente!
Para saber mais sobre o DataStore, confira nossa documentação e pratique com nossos codelabs Proto DataStore e Preferences DataStore.
nice article info bor metrolagu
Postar um comentário
Um comentário :
nice article info bor metrolagu
Postar um comentário