Depois de entendermos como criar aplicativos híbridos usando o Kotlin Multiplatform, chegou a hora de aprender sobre as principais opções de armazenamento de dados em dispositivos móveis usando o Kotlin. No desenvolvimento de aplicativos Android, é essencial escolher a abordagem correta para armazenar informações de forma eficiente e segura; sendo assim, nesta lição, exploraremos o uso do Room, uma biblioteca que facilita a persistência de dados usando bancos de dados SQLite, e o Shared Preferences, que permite armazenar pequenas quantidades de dados de forma simples e rápida.
Além disso, discutiremos boas práticas para gerenciamento de dados, garantindo a integridade e segurança das informações do usuário. Ao final desta lição, você será capaz de aplicar essas técnicas em seus projetos para criar aplicativos mais robustos e eficientes. Vamos começar?
Ao desenvolver um aplicativo de anotações para dispositivos móveis, garantir que os dados do usuário sejam armazenados de forma segura e acessível, mesmo sem conexão com a internet, é um desafio. Se as informações forem mantidas apenas na memória, elas serão perdidas assim que o aplicativo for fechado. Por outro lado, se utilizarmos um banco de dados para todas as informações, até mesmo para salvar configurações simples, como a preferência pelo tema escuro ou claro, pode tornar o sistema mais complexo do que o necessário.
Nessa problematização, é essencial escolher o tipo de armazenamento mais adequado para cada necessidade. Mas como garantir a persistência das notas de forma eficiente? Quando optar por um banco de dados estruturado, como o Room, e quando utilizar o Shared Preferences para armazenar configurações leves? Compreender essas opções permite desenvolver aplicativos mais eficientes, organizados e adaptados às necessidades reais dos usuários.
Vamos entender melhor sobre isso?
Agora, vamos entender como o armazenamento de dados em dispositivos móveis funciona na prática? Para facilitar sua compreensão, conheça a empresa fictícia NoteFast que está desenvolvendo um aplicativo de anotações rápidas para smartphones Android. O objetivo é permitir que os usuários criem, editem e excluam notas de maneira intuitiva. Para isso, inicialmente, a equipe pensou em armazenar as anotações apenas na memória, mas percebeu que os dados eram perdidos ao fechar o aplicativo. Para resolver isso, a equipe decidiu utilizar o Room, garantindo que as notas fossem armazenadas de forma persistente.
Essa não foi, porém, a única decisão da equipe! Para melhorar a experiência do usuário, o Shared Preferences foi implementado para salvar configurações do aplicativo, como o modo escuro ativado ou não. Dessa forma, o usuário conseguiria personalizar a interface e manter suas preferências salvas mesmo após reiniciar o dispositivo. Com essas soluções, o aplicativo se tornou mais funcional e confiável, garantindo uma ótima experiência para os usuários.
Portanto, por meio do exemplo desse case, é possível compreender a importância de escolher o método de armazenamento adequado para cada tipo de dado. Além disso, é uma situação que ilustra a aplicação de conceitos, como bancos de dados locais (Room) para armazenar informações essenciais e Shared Preferences para salvar configurações leves, criando aplicativos mais eficientes e adaptáveis às necessidades dos usuários. Agora, tendo um pouco mais de conhecimento sobre o assunto, vamos nos aprofundar!
O armazenamento de dados é um aspecto fundamental no desenvolvimento de aplicações Android, garantindo que informações importantes sejam preservadas mesmo após o fechamento do aplicativo. Dependendo da necessidade da aplicação, diferentes estratégias podem ser adotadas para armazenar e recuperar dados de maneira eficiente, garantindo uma boa experiência ao usuário. No Android, há uma variedade de soluções disponíveis, cada uma adequada para um tipo específico de dado e contexto de uso. Resende (2018) destaca que podemos utilizar quatro formas principais de armazenar os dados da sua aplicação. Conheça cada uma delas:
Shared Preferences: armazena pequenos dados como configurações e preferências do usuário em arquivos XML. Resende (2018) complementa dizendo que é um tipo de persistência muito simples, em que os dados são armazenados por chave-valor.
Room Database: uma camada de abstração sobre o SQLite que facilita a criação e manipulação de bancos de dados locais. Resende (2018) diz que é a solução mais completa que podemos ter para dados estruturados.
Arquivos locais: permite salvar documentos, imagens e outros arquivos diretamente no armazenamento do dispositivo. Resende (2018) diz que usamos esse tipo quando precisamos armazenar arquivos somente no contexto do nosso App.
Banco de dados na nuvem: soluções, como Firebase, que, segundo Machado (2021), é uma estrutura recheada de recursos oferecida pelo Google, permitem armazenar dados on-line e sincronizá-los entre dispositivos.
O Shared Preference é uma forma de armazenamento ideal para pequenas configurações, como o estado de login ou o tema do aplicativo. De acordo com Resende (2018), geralmente ele é utilizado para guardar preferências dos usuários, por exemplo, “manter-se conectado”. Veja a seguir, na Figura 1, um exemplo de Shared Preference para salvar a preferência do usuário pelo tema escuro:
Explicação do código:
Linha 1: crio um Shared Preference com o nome de AppPrefs.
Linha 2: atribuo para uma variável editor o editor de Shared Preferences.
Linha 3: salvo no SP um valor verdadeiro para o modo escuro do tema do aplicativo.
linha 4: aplico as alterações feitas pelo editor.
Uma vez que foram salvas essas preferências, conseguimos, também, recuperar o valor para validação em nossa regra de negócio, como:
val modoEscuro = sharedPreferences.getBoolean(“modoEscuro”, false)
O Room Database simplifica o uso do SQLite, tornando o código mais organizado e seguro. Segundo Resende (2018), por ser a solução mais completa, uma das principais vantagens do Room é a capacidade de implementar um banco de dados SQLite inteiro utilizando uma abordagem ORM (Object-Relational Mapping), que facilita significativamente a manipulação dos dados. Com o Room, é possível criar entidades (tabelas) e realizar operações, como inserção, leitura, atualização e exclusão de dados, de forma mais eficiente e com menor chance de erros.
Na Figura 2, apresento a você um exemplo básico de implementação do Room em Kotlin. Nesse exemplo, a criação de uma entidade é feita por meio de classes anotadas com @Entity, conforme explicita Resende (2018). Essas anotações indicam ao banco de dados que a estrutura de dados definida pela classe será mapeada como uma tabela dentro do banco.
Pontos a serem entendidos no código:
A anotação @Entity na linha 1, que define a classe como uma entidade (tabela), e a anotação @PrimaryKey(autoGenerate = true), que define o atributo id como a chave primária da entidade, sendo gerada automaticamente.
O Room também exige a criação de uma classe DAO para cada entidade. Resende (2018) explica que DAO é a abreviação de Data Access Object (objeto de acesso a dados) e que esse é um padrão comum em projetos de software que acessam bancos de dados. Assim, veja, na Figura 3, uma implementação da NotaDao:
Pontos a serem entendidos no código:
A anotação @Dao na linha 1, que informa a utilidade da interface, @Insert na linha 3, que informa que a função inserirNota insere dados no banco de dados, e @Query(“SELECT * FROM Nota”), que seleciona todos os registros da entidade Nota, o que, por consequência, seleciona todos os registros da tabela notas do banco de dados, por meio da função listarNotas().
Para que tudo funcione corretamente, é necessário também criar o banco de dados; caso contrário, nada terá efeito. Resende (2018) explica que essa é a última parte da implementação do Room, que envolve a criação do objeto de banco de dados. Por isso, na Figura 4, irei mostrar como criar um banco de dados utilizando o Room:
Pontos a serem entendidos no código:
A anotação @Database(entities = [Nota::class], version = 1), que cria o banco de dados e as respectivas tabelas ou entities que precisam ser registradas como a entidade Nota foi. Além disso, define a versão do banco de dados, que sempre começa com o valor 1.
Agora que temos a entidade, o DAO e o banco de dados criados, a próxima dúvida é: como utilizá-los? Na Figura 5, mostro a você como salvar uma nota utilizando a estrutura que criamos:
Pontos a serem entendidos no código:
Entre as linhas 1 e 4, estamos criando o banco de dados com o título notas-database usando o databaseBuilder do Room e nossa classe AppDatabase.
Na linha 6, instanciamos o objeto notaDao para fazer as operações com a entidade.
Na linha 7, instanciamos um objeto Nota com titulo e conteudo.
Na linha 8, usamos notaDao por meio de seu método inserirNota() para inserir a nota criada.
Com essa abordagem, os dados são armazenados de forma persistente e podem ser acessados sempre que necessário. O uso de Shared Preferences e Room com Kotlin oferece soluções eficazes para o armazenamento de dados em aplicativos Android, cada uma adequada a necessidades específicas.
O Shared Preferences é ideal para armazenar pequenas quantidades de dados simples, como configurações de usuário e preferências de interface, de forma rápida e eficiente. Por outro lado, o Room oferece uma poderosa abstração sobre o SQLite, permitindo a persistência de dados estruturados com segurança e escalabilidade. É a melhor opção para armazenar informações mais complexas, como listas de notas ou registros de usuários. Ao combinar essas tecnologias de maneira adequada, os desenvolvedores podem criar aplicativos robustos, garantindo eficiência, persistência e uma experiência aprimorada para o usuário.
Compreender o uso do Room e do Shared Preferences é essencial para você, futuro técnico em Desenvolvimento de Sistemas, pois permite implementar soluções eficientes para armazenamento e persistência de dados em aplicativos Android. Enquanto o Room facilita a manipulação de bancos de dados SQLite de forma segura e organizada, o Shared Preferences possibilita salvar pequenas configurações do usuário sem a complexidade de um banco de dados completo. Agora, entendendo melhor a teoria, vamos colocar isso em prática!
Como já compreendemos os conceitos de armazenamento de dados utilizando Room e Shared Preferences, é hora de aplicar esse conhecimento em um desafio prático. Vamos desenvolver um aplicativo de anotações, onde o usuário poderá cadastrar suas notas utilizando o Kotlin e o Jetpack Compose.
Para esse desenvolvimento, siga o passo a passo:
1) Crie um projeto no Android Studio usando Kotlin e Jetpack Compose como nas lições anteriores.
2) Configuração do projeto:
a) Certifique-se de que as dependências do Room estão corretamente configuradas no build.gradle.kts.
i) Em plugins, inclua a linha alias(libs.plugins.ksp),
ii) Em dependencies, inclua as três linhas a seguir:
(1) implementation(libs.androidx.room.runtime)
(2) implementation(libs.androidx.room.ktx)
(3) ksp(libs.androidx.room.compiler)
b) No arquivo libs.versions.toml, inclua:
i) Em versions, inclua kspVersion = "1.9.0-1.0.13"
ii) Em libraries, inclua a linha: androidx-room-ksp = { module = "androidx.room:room-compiler", version.ref = "roomRuntime" }
iii) Em plugins, inclua a linha: ksp = { id = "com.google.devtools.ksp", version.ref = "kspVersion" }
c) Adicione as permissões necessárias para acessar o armazenamento local, se necessário.
3) Criação das classes:
a) Classe Nota (Figura 2): definição da entidade do banco de dados para armazenar as anotações.
b) Interface NotaDao (Figura 3): criação do DAO para inserir e recuperar notas no banco de dados.
c) Classe AppDatabase (Figura 4): implementação do banco de dados utilizando Room.
4) Implementar o código da Figura 6 que implementa a MainActivity:
5) Na sequência, implemente o componente NotaCadastroScreen() na Figura 7:
Com esse desafio, você implementou a persistência de dados utilizando o ORM Room. Agora, desafie seus colegas e/ou professores a criar a tela que visualização das notas salvas. E aí, pronto para esse novo desafio?
MACHADO, K. Angular 11 e Firebase: construindo uma aplicação integrada com a plataforma do Google. São Paulo: Casa do Código, 2021.
RESENDE, K. Kotlin com Android: crie aplicativos de maneira fácil e divertida. São Paulo: Casa do Código, 2018.