- 2 de maio de 2023
- Blog
Porque um projeto Android tem essa estrutura
Se você tem experiência como desenvolvedor Android, provavelmente já viu essa estrutura abaixo:
Você já se perguntou por que essa estrutura é assim?
Para os novatos, não é lá grande coisa tentar entender porque ela é assim ou o que é cada um desses arquivos, justamente pelo fato de não depender disso para desenvolver um app decente (na maioria das vezes).
Esse artigo é para aqueles que querem saber o que são cada um desses arquivos e o porquê dessa estrutura de uma forma suave (quero dizer, tentarei ser simples) e como isso funciona desde sempre.
Perguntas Idiotas ajudam 🥴
Quero dizer, antes de começar, eu gostaria de fazer um exercício com o processo de pensar para descobrir o que estamos buscando com perguntas simples e talvez idiotas, mas irão nos ajudar a entender. Vamos lá:
Primeira: O que é, de uma forma simples, um aplicativo Android?
Basicamente, é um app que funciona dentro de um sistema Android (seu celular Android usa esse sistema), certo🤌?
Segunda: Mas, como um celular Android reconhece um app, para mostrar no lugar certo? Como ele sabe que o código que escrevi é para um aplicativo Android?
Você provavelmente pensou: “através do Android App Bundle ou um Apk”. Não vou falar das diferenças entre eles, mas são arquivos que contém uma monte de informação compilada (você provavelmente já sabe disso), como:
- recursos: que podem ser imagens, vídeos, arquivos, ou algo semelhante;
- código fonte: o código que você usou para escrever o código do app;
- fonte de pacote: um conjunto de dependências, como bibliotecas.
Considerando o fato de que compilar essas informações quer dizer que elas serão organizadas e comprimidas seguindo um padrão para gerar um arquivo que pode ser um Apk ou um App bundle, nós sabemos, então, que precisamos “fazer” algo ou encontrar alguém que “faça” essa compilação para gente.
É, o “cara” que “faz” isso pra gente é chamado de, chan chan chan chan… ANDROID BUILD SYSTEM.
Até aqui ok, mas por que eu preciso saber isso para entender a estrutura do projeto?🤔
Boa pergunta jovem mancebo🤓
Tudo isso faz parte do “Android build process” ou processo de construção Android.
O Android Build System tem um processo para seguir para gerar o apk, você pode checar esse artigo para entender como ele funciona:
Estamos chegando lá, paciência…
Porém, fazer esse processo na mão é loucura total. É muito complexo e envolve um monte de ferramentas.
O Android Studio torna esse processo mais fácil com uma ferramenta avançada de construção que automatiza para nós todo esse processo chamado Gradle. Há outra ferramenta também que faz o mesmo chamada Bazel, mas não é oficialmente suportada pelo AS.
Isso mesmo, se você é um desenvolvedor Android, já se deparou com o Gradle várias vezes (não especificamente com ele, mas com suas abordagens).
Mas, quem é o culpado pela estrutura do projeto ser assim? E por que eu preciso saber tudo isso😑?
A resposta é, principalmente, a IDE. A maior parte da culpa do projeto ser estruturado assim é por causa do Android Studio. Pode parecer óbvio, mas espere, deixe-me explicar! Para nós construirmos nosso app na mão, nós precisamos somente da seguinte estrutura:
- pasta do projeto: a pasta raiz para colocar os arquivos do projeto;
- pasta de bibliotecas: a pasta que contém os pacotes/bibliotecas usados no projeto;
- pasta de recursos: a pasta que contém nossos recursos, como imagens e companhia;
- pasta do código fonte: a pasta que conterá nosso código para construir o app.
Percebeu? Isso, essas pastas fornecem para nós as mesmas informações mencionadas no topo do artigo para compilar um apk🎉.
O Android Studio tem o papel de usar ferramentas para automatizar o processo “manual” de criação da app. Até esse ponto, não precisamos exatamente dessa estrutura para fazer um app, isso tudo é porque o Android Studio toma conta do “grosso” e da parte clichê.
Se você esqueceu de tomar seus remédios 🤒 e gostaria the “bulidar” seu app do seu jeito sem usar o Gradle e o AS, dá um pulo aqui!
Ok, Bora fazer um tour pela estrutura do projeto usando o Android Studio✈️:
Como você sabe, nós usamos o Gradle para cuidar do processo de criação no Android Studio. É importante entender sua configuração no projeto.
Gradle é uma ferramenta de automação de criação, não só para apps Android. Isso quer dizer que ele é flexível e é usado para outras tecnologias e linguagens.
Seu poder está no fato de que ele é capaz de fazer algumas suposições de como construir alguma coisa (independente da linguagem). Isso faz dele flexível e super poderoso.
Mas, como ele sabe como construir um sistema específico como o Android? Muito simples, pelos arquivos de configurações.
Para o sistema Android, nós temos 4 arquivos de configuração Gradle e cada um pode usar tanto groovy (arquivo.gradle) ou kotlin script (file.gradle.kts):
- Arquivo Settings: Esse arquivo de configuração define os repositórios de nível projeto para as configurações e informa ao Gradle quais módulos ele deve incluir quando estiver construindo seu aplicativo. Projetos multi-módulos precisam especificar cada módulo que deve ir na construção final. Geralmente se parece como:
https://gist.github.com/PabloProta/aade6abfa009bfe1f54405da279df0d9
- Arquivo Top level Build: Também localizado na raiz do diretório do projeto, ele define as dependências para aplicar em todos os módulos (isso não quer dizer que eles vão ser injetados no seu módulo). Por padrão, o arquivo topo de construção usa o bloco de código plugins para definir as dependências do Gradle que são comuns para todos os módulos no projeto. O seguinte código de exemplo descreve a configuração padrão e os elementos DSL no arquivo top-level build.gradle depois de criar um projeto novo:
https://gist.github.com/PabloProta/053546c9a5c70be1df3e517f0427bc10#file-build-gradle-kts
- Arquivo build nível Modulo: Localizado no diretório projeto/modulo/, ele permite configurar seu arquivo de construção para um módulo específico. Configurando este arquivo, é possível adicionar uma configuração personalizada de empacotamento, como buildTypes e flavors, e sobrescrever configurações no manifesto que estão dentro de main/no módulo de app ou no arquivo gradle ou build.gradle.kts no top do projeto:
https://gist.github.com/PabloProta/7fdfe263deef3e12880687e347d85f73#file-build-gradle-kts
Como você pode observar, estamos usando o plugin id(“com.Android.application”), que nos permite adicionar o bloco de configuração Android { }. Essa configuração diz ao projeto do aplicativo que aquele módulo vai ser usado como um módulo Android, provavelmente com dependências Android, como alguns componentes Android.
Sem esse plugin, não é possível usar nenhuma resolução de dependência de referências Android, como:
implementation 'Androidx.core-ktx:1.7.0' implementation 'Androidx.appcompat:appcompat:1.6.1'
Essas dependências dependem (isso até soa engraçado) da referência do arquivo de classe para o código fonte. Quem vai aplicar algumas configurações para compilar corretamente essas referências de arquivos de classes é a configuração posta no bloco android { } , que é provido pelo plugin id(“com.Android.application”).
Como você pode perceber, os repositórios usados como maven central são usados como artefatos tanto para os plugins como para as dependências.
- Arquivos de propriedade: Gradle também inclui dois arquivos de propriedade localizados na raiz do projeto, que você pode usar para especificar instruções de configuração para o Gradle gradle.properties. É aqui que você pode definir as configurações do Gradle em todo o projeto, como o tamanho máximo de heap do daemon do Gradle. Para obter mais informações, consulte Criar ambiente.
https://gist.github.com/PabloProta/2a627ffa878488604a1402feed7368e8#file-gradle-properties
- properties Configura as propriedades do ambiente local para o sistema de compilação, incluindo o seguinte:
- dir – Caminho para o NDK. Esta propriedade foi preterida. Todas as versões baixadas do NDK são instaladas no ndkdiretório dentro do diretório Android SDK.
- dir – Caminho para o SDK.
- dir – Caminho para CMake.
- symlinkdir – No Android Studio 3.5 e superior, cria um link simbólico para o NDK que pode ser mais curto que o caminho do NDK instalado.
No meu exemplo, eu só defino o diretório SDK, você pode colocar seu caminho SDK:
https://gist.github.com/PabloProta/7bc25cc696bb58d159019b8937a14899#file-local-properties
Isso não acaba? Calma lá, estamos chegando🌅
Estamos finalizando, neste ponto já verificamos os pontos mais complexos:
Vamos falar sobre o wrapper Gradle que está localizado em project/gradle/wrapper:
Por padrão, a pasta Gradle contém as propriedades do Gradle wrapper usado para baixar o Gradle sem precisar ter o Gradle instalado em nossa máquina, basta instalar no projeto e ele é automaticamente baixado pelo Android studio e é atualizado, basta configurar o plug-in Android Gradle nas preferências do projeto. É assim que parece:
https://gist.github.com/PabloProta/b050ed591ce9373e8aa54583919a5709#file-wrapper-properties
Além disso, no diretório raiz há dois arquivos chamados gradlew e gradlew.bat (se você estiver em um ambiente de sistema operacional Windows). Eles são um script de shell e um script de lote do Windows, respectivamente, para executar a compilação com o Wrapper .
Veja esta imagem, já verificamos quase tudo:
O .gitignore
Os arquivos .gitignore servem para controle de versão. gitignore basicamente vai ignorar alguns arquivos para controle de versão que não gostaríamos de comitar em nossos commits, como arquivos de build e alguns arquivos de configuração da IDE, que são inúteis para serem comitados, afinal eles são gerados automaticamente e vão tornar o commit maior sem necessidade.
.Idea
É uma pasta responsável por conter alguns arquivos que configuram a IDE para nossos projetos. Não temos e nem devemos alterar esses arquivos, eles são gerados automaticamente enquanto você está desenvolvendo e não precisa se preocupar com eles.
.gradle
Este é uma pasta autogerada just-in-time, geralmente quando você executa o Gradle pela primeira vez em nosso projeto. De forma geral, quando você está abrindo seu projeto pela primeira vez, você pode excluí-lo, mas pode ser necessário executar o Gradle novamente para regenerá-lo.
UHULL APENAS O CAMINHO DO APLICATIVO AGORA!
Olha 👀:
Já falamos sobre .gitignore e build gradle, mas… o que é o proguard-rules.pro? É como uma máquina exterminadora de código vírus, ou algo parecido👾 🤖? Não, apenas um arquivo para aplicar algumas regras para reduzir o tamanho do aplicativo, como remover algumas classes e métodos ou ofuscá-los se necessário.
Por padrão, nas versões mais altas do Gradle, a redução do aplicativo é feita pelo compilador R8 que já vem com ele. Mas, mesmo vindo por padrão, você precisa habilitá-lo nas configurações de build do módulo:
https://gist.github.com/PabloProta/29f4457f9113a27ecc3f016c3e4e6dc7#file-build-gradle-kts
Mas se você verificar seu arquivo proguard, ele estará em branco com todas as linhas comentadas por “#”:
O projeto na verdade está sim encolhendo (se configurado em alguma versão, como release) mesmo que o proguard rules esteja vazio. O que fazemos nesse arquivo é aplicar regra não padrões ao encolhimento do código (como evitar que alguma classe seja reduzida ou alterar algum comportamento padrão do compilador).
Módulo de sourcesets:
Temos 3 caminhos, geralmente:
main: o sourceset que contém o código principal para fazer nosso aplicativo que você provavelmente conhece, é onde você terá seu código principal.
Também temos o AndroidManifest.xml, um arquivo XML que contém metadados importantes sobre o aplicativo Android. Isso inclui o nome do pacote, nomes de atividade, atividade principal (o ponto de entrada para o aplicativo), suporte à versão do Android, suporte a recursos de hardware, permissões e outras configurações;
- AndroidTest (opcional): é o sourceset para o teste instrumentado do Android. Não é uma abordagem obrigatória, mas é uma boa prática fazer algum teste de instrumentação;
- test (opcional): para testes unitários e teste de integração que não estão vinculados ao framework Android).
Por último, mas não menos importante, a pasta de recursos
A pasta que conterá os recursos como imagens, vídeos, strings, drawables, cores etc. usados no módulo do conjunto de fontes principal ou qualquer build variant ou flavor sourceset.
_________________________________________________________________________
FINALMENTE, ACABAMOS ❤
Apresentei todos os tópicos contidos no projeto do aplicativo Android e espero que tenha sido claro e útil para entender a estrutura do projeto Android e por que ele é assim. Fique à vontade para sugerir e compartilhar este artigo, obrigado S2.