25%OFF no 1º ano | 50%OFF No 2º ano

Últimos dias!

Últimos dias!

00

DIAS

00

HORAS

00

MIN

00

SEG

Alura > Cursos de Mobile > Cursos de Android > Conteúdos de Android > Primeiras aulas do curso Android Room parte 1: entendendo e aplicando a persistência de dados com ORM

Android Room parte 1: entendendo e aplicando a persistência de dados com ORM

Conhecendo as opções de armazenamento - Introdução

Meu nome é Alex Felipe e eu vou apresentar a primeira parte do curso de persistência no Android com room. Antes mesmo de falar das novidades do curso, quero dar uma introdução sobre o projeto que a gente vai utilizar, que se trata de uma agenda de alunos. Caso você não tenha a mínima ideia sobre o que é esse projeto, ele é desenvolvido nos três primeiros cursos'de fundamento de Android da Alura. Recomendo fortemente que você faça esses cursos para poder continuar com esse, porque vou assumir que você já saiba todo o conteúdo ensinado nesses cursos anteriores.

Então vamos entender nosso projeto, os comportamentos comuns e o problema que nós vamos solucionar Nesse projeto temos os comportamentos de CRUD para os nossos alunos como e o caso da inserção de um aluno. Vou adicionar aqui um aluno, o Gui, a gente tem a capacidade de fazer a alteração, outra ação dentro do CRUD, e a remoção.

Só que esses comportamentos só funcionam junto com o aplicativo, ou seja todos esses dados estão armazenados apenas em memória no curso de fundamentos que desenvolvemos.Dada essa situação, sabemos que é comum um aplicativo manter os dados do usuário, afinal não faz sentido algum um usuário preencher todos os dados na agenda e perceber que as informações sumiram.

Então partindo desse problema vamos entender que o Android como Framework já não oferece alternativas para lidar com isso, as opções de armazenamento. Vamos entender como funcionam essas opções dentro do Android e ver que dentre elas há uma opção como o banco de dados que utiliza o SQLite como ferramenta para nos orientar, e dessa maneira a gente consegue salvar os nossos dados e mantê-los para nosso usuário.

Mas é claro que existem muitos desafios para poder manter esse tipo de implementação porque o SQLite por exemplo é uma API que utiliza um código de baixo nível. Pra conseguir colocar toda essa estrutura de banco de dados para as informações persistirem dá um certo trabalho e a própria documentação do Android recomenda pra isso uma ferramenta conhecida como Room.

Vamos focar no Room durante o curso. Ele é muito bom em relação ao SQ Lite puro a baixo nível. Por exemplo, vai ter peculiaridades como seus três principais componentes: o DataBase, o DAO, e o Entity. Vamos aprender como funcionam suas implementações, quais são as preocupações que precisamos ter, e vamos perceber também que essa ferramenta se trata do Jetpack do Android,aquela coleção de bibliotecas que vão te ajudar a construir um aplicativo e no seu desenvolvimento.

Olhando mais abaixo, vemos que ele faz parte do Architecture Components ou componentes de arquitetura e temos o Room como ferramenta. Vamos focar no Room e não em outras APIs do Architecture Components, para antecipar, como é o caso do View Model ou o LiveData. Vamos aprender só sobre ele, principalmente na parte de persistência e implementação.

Aprenderemos também como fazer Migrations e que há uma certa complexidade para fazer Migrations e manter da maneira esperada, além da conversão de tipos de dados que não são automaticamente convertidos para o SQLite. O nosso foco durante a finalização do curso é que no momento que fizermos uma operação no aplicativo, os dados sejam mantidos dentro do dispositivo, celular.

Conhecendo as opções de armazenamento - Entendendo o SQLite

O nosso aplicativo é capaz de realizar operações básicas de CRUD, porém para o nosso usuário final ainda há alguns problemas que precisamos prestar atenção. Precisamos saber se conseguimos adicionar o aluno, como é o caso de adicionar o Gui, mas depois que fazemos essa adição acontece o seguinte: se fechamos o nosso aplicativo o Gui há não existe mais.

Isso acontece justamente pelo fato de que a nossa implementação foi feita via memória, ou seja, ela é mantida de maneira estática enquanto o aplicativo está de pé, e qualquer ação que faça o nosso aplicativo fechar, ou melhor, ser reiniciado,vai fazer com que nosso dado seja perdido, como é o caso de operações comuns para qualquer tipo de usuário.

Se vamos lá e fechamos sem querer, se reinicia o celular ou a bateria do celular acaba, é muito comum o aplicativo ser fechado. E manter essa solução que só funciona enquanto o aplicativo estiver de pé pode fazer com que o nosso usuário não tenha uma experiência bacana e pode até tornar o app inutilizável porque não vai ser capaz de atender uma necessidade.

Pensando nesses detalhes: melhorar a experiência do usuário e também garantir a integridade dos seus dados, vamos aprender agora algumas alternativas existentes no Abdroid para permitir esse tipo de abordagem.

Além da implementação via memória, o próprio Framework do Android oferece as opções de armazenamento ou Storage Options. Elas são algumas técnicas disponíveis dentro do Framework que permitem salvar os dados. Existem quatro principais tipos de armazenamento para dados internos. Veremos o que isso significa e quais as propostas para cada um deles.

Aqui no começo temos o Internal file storage, o armazenamento de arquivos internos. Ele fala um pouco o que isso significa. Se quisermos armazenar alguns arquivos de maneira privada, de forma que apenas o nosso aplicativo teria acesso, essa seria uma alternativa interessante. 'Da mesma maneira temos o External file storage, uma abordagem similar, mas a diferença é que podemos, por exemplo, armazenar fotos que seriam disponibilizadas numa galeria para nosso usuário. São arquivos compartilhados.

Temos também o Shared preferences que seria uma técnica pela qual conseguimos armazenar valores primitivos como apenas uma String, apenas um inteiro. Na tradução seria "preferências compartilhadas". Por fim temos o Databases, pelo qual conseguimos armazenar dados estruturados como se fossem tabelas. Percebendo nossa necessidade atual, precisamos de uma técnica que permita a adição de um dado estruturado. Afinal o armazenamento de um aluno pode ser um dado estruturado.

Então esse Databases, que significa "banco de dados, é uma técnica que podemos considerar usar. É o que veremos durante o curso. Clicando na documentação para olhar esse tópico, percebemos que o Android Framework dá suporte a uma API nativa chamada de SQLite que nada mais é do que uma implementação de banco de dados. No site do SQLite podemos entender melhor o que ele significa e que ele é um banco de dados comum como o o caso do MySQL, Oracle, SQLServer e assim por diante. Tem alguns comportamentos bem similares. A diferença é que é uma implementação mais enxuta, mais simples e rápido para atender o mercado de dispositivos móveis, não forçando um dispositivo móvel a manter um banco de dados pesado, de alta computação. Por isso utilizamos o SQLite no Android.

Sabemos que o SQLite é que vai fornecer a técnica de banco de dados para nós, mas se usarmos API nativa do próprio Framework veremos algumas peculiaridades. Lendo um pouco sobre sobre as propostas, ele sugere usar uma Lib chamada Room. Isso porque no momento que usamos o SQL lidamos com um código de baixo nível, ou Low Level, o que significa que é necessários muito código para alcançar a estrutura desejada na solução. Fiz inclusive a implementação mostrando como seria a implementação do nosso DAO utilizando o SQLite. Isso em Low Level. Pegando nosso aluno DAO em Low Level, consigo mostrar o que temos de código para fazer uma implementação que atende exatamente os mesmos comportamentos que temos em memória.

Aqui podemos ver onde criamos nossa tabela via código SQL, temos outro método em que não fazemos nada, mas somos obrigados a a sobrescrevê-lo. Há os métodos salva, edita, todos, e outras peculiaridades. Não vou entrar e muitos detalhes sobre cada um deses tópicos, ate porque não é objetivo do curso, mas quis mostrar a complexidade para fazer essa implementação e algumas das motivações que a documentação comenta, por exemplo, não ter uma verificação em tempo de compilação sobre problemas possíveis na nossa Query SQL. Esse é um dos detalhes ao se considerar a API nativa.

Se de repente há alguma mudança no esquema temos que mudar tudo manualmente, seja a própria tabela no banco de dados, seja os métodos que realizam as operações, o que mostrei pra vocês, e tudo isso está propenso a erros, como menciona a documentação. E é claro, para fazer uma conversão do que seria código SQL para objeto, ou vice-versa, temos o que se chama Boilerplates, códigos repetitivos que aparecem muitas vezes durante o código maior, sendo que poderíamos usar uma camada que abstrai esses comportamentos, o caso do Room.

Perceba o seguinte: o objetivo do curso é perceber que temos opções e saber que temos uma biblioteca que pode facilitar nossa vida, para termos aqueles comportamentos bacanas para o usuário se ele quer manter os dados garantidos, salvos independentemente de fechar ou reiniciar o aplicativo e assim por diante, e também que não tenhamos a dificuldade de implementar usando a API nativa, que é o SQLite, em Low Level (baixo nível). Essa foi a introdução para entender que vamos usar o SQLite, mas teremos uma biblioteca capaz de facilitar todo o procedimento, o Room. A seguir veremos um pouco mais o que é o Room, qual é a proposta dele e o que podemos tirar de proveito para facilitar a nossa implementação.

Conhecendo as opções de armazenamento - Adicionando o Room ao projeto

Antes de começarmos a implementar o Room ao nosso projeto, vou aproveitar o momento para fazer uma introdução sobre o que é o Room,o conceito por debaixo dos panos e como ele se encaixa do Android Framework. Sobre essa questão do que é o Room, sabemos que ele é uma biblioteca capaz de abstrair a comunicação que temos entre o aplicativo e o banco de dados, evitando a implementação em baixo nível que o SQLite nos provê. Então em vez de fazer todo o código, a ideia é que tenhamos uma comunicação em alto nível.

Se eu quero salvar um aluno, vou fazer, por exemplo, uma chamada de um método insert ou salva, algo do gênero. O próprio Room vai ser capaz de pegar todas as configurações que vamos fazer e gerar todo o código pra nós. A ideia é basicamente essa. Pode parecer mágico pensar nesse tipo de cenário de ter essas classes e o Room fazer toda essa interpretação pra mim. Mas pra isso existe um conceito que já é bem desenvolvido na comunidade de software chamado de ORM, na tradução "mapeamento objeto-relacional" ou em inglês Object-relational mapping.

Por essa técnica vamos ter nossos objetos que vão representar o que seria uma classe. e o banco de dados, o que seriam as tabelas. As ferramentas que implementam esse tipo de conceito vão pegar todas as nossas classes e vão gerar todo o código pra gente, permitindo que não tenhamos que fazer todo o mapeamento de maneira manual, escrevendo o código SQL se preocupando a cada mudança. A própria ferramenta fica responsável por isso. Esse conceito é chamado de ORM, que é justamente abstrair o que temos de objetos para o que teremos de banco de dados. O Room utiliza esse tipo de conceito para fazer essa implementação.

Outra coisa importante que precisamos saber sobre o Room é que ele faz parte de uma coleção de bibliotecas que tende a facilitar a implementação do nosso projeto, o Jetpack. O Jetpack é um conjunto de bibliotecas que a comunidade de desenvolvedores acabou adotando e indicando como soluções que vão ser comuns aos projetos e facilitar sua vida, e o Room faz parte das bibliotecas agregadas a essa página. Em específico do Room há a categoria Architecture, ou então, entrando um pouco mais nesse assunto, temos os Architeture components onde está o Room. Eles têm o objetivo de deixar seu aplicativo mais robusto, mais fácil de utilizar ou até mesmo oferecer manutenção. Então essa é uma vantagem muito boa.

'Nesse curso trataremos especificamente do Room, não abordaremos outras APIs que fazem integração com ele, o que seria assunto para um outro curso a ser ensinado mais para frente.

Agora que já tivemos essa introdução vamos fazer a adição do Room no nosso projeto para logo a seguir fazer a implementação. Para isso voltamos naquela página que eu havia mostrado pra vocês e clicaremos no link que mostra que para adicionar o Room teremos um script, uma dependência que colocaremos no projeto, afinal ele é uma biblioteca externa.

Temos dois tópicos sobre os quais é muito importante pensar O tópico Android X é a biblioteca capaz de dar suporte a APIs antigas do Android, com a proposta de substituir o Android Support. Mais pra frente, talvez no momento em que você fizer esse curso, você já utilize essa versão do Android Support. Eu vou usar uma pré-versão do Android X. Não vou dar atenção aos scripts opcionais porque esse é um outro passo após uma introdução com o Room. Só vou adicionar os três primeiros scripts copiando e colando ao nosso projeto para que ele consiga buscar e configurar o Room.

Para adicionar as dependências ao nosso projeto, acessaremos o Gradle script, ou então podemos pesquisar via Ctrl + Shift + N, e nesse build.gradle do módulo app é onde colocamos nossas dependências, no Script dependences. Eu vou dar um Enter para dar um espaço e depois um Ctrl + V. Para aumentar o código, clico em Ctrl + Shift + F12.

Vou apertar o botão aqui de cima para sincronizar com o projeto e enquanto isso dar uma introdução do que significa cada um dos itens que foi adicionado com o script. Esse def room_version vai ser uma variável que colocaremos no nosso arquivo de build. Essa variável vai ser colocada desse jeito porque tem dois carinhas que fazem uso dela no código, então tem que ser exatamente a mesma versão. Utilizando uma variável, evitamos um erro de digitação, por exemplo, por isso foi considerada essa abordagem.

Essa parte do implementation basicamente é a própria API, a própria Lib do Room. Abaixo temos o annotationProcessor que é uma entidade capaz de gerar código a partir de metadados. Essa técnica já foi introduzida desde a versão 5 do Java e é uma ferramenta muito poderosa capaz de gerar código automaticamente com base em um tipo de configuração. Em outras palavras essa é a parte fundamental do Room porque a partir desse annotationProcessor que conseguiremos configurar os objetos definindo se o aluno tem que ser uma tabela e assim por diante, o Room vai entender isso e gerar o código. Além disso a partir dessa técnica ele vai fazer um tipo de checagem indicando se pode funcionar escrever um código SQL para fazer uma Query personalizada. Então ele vai ser uma entidade que em tempo de compilação vai gerar o código em SQLite em baixo nível. É essa a maneira que o Room funciona e é muito importante ter as duas anotações adicionadas, tanto implementation que é o próprio Room e o annotationProcessor que é o processador após a compilação e vai gerar o código pra gente.

Uma observação: caso você utilizasse o Kotlin para implementar o Room, teria que usar kapt ao invés do annotationProcessor. Você só copiaria o kapt e o colocaria no lugar do annotationProcesor e conseguiria utilizá-lo.

Vou sincronizá-lo novamente e ver se tudo funciona de maneira esperada, até abrindo o Build, e já conseguimos colocar o Room. Agora que entendemos o que é o Room, sua proposta, conceito e como ele se encaixa, vamos começar a seguir com a implementação.

Sobre o curso Android Room parte 1: entendendo e aplicando a persistência de dados com ORM

O curso Android Room parte 1: entendendo e aplicando a persistência de dados com ORM possui 152 minutos de vídeos, em um total de 49 atividades. Gostou? Conheça nossos outros cursos de Android em Mobile, ou leia nossos artigos de Mobile.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Android acessando integralmente esse e outros cursos, comece hoje!