Projeto Android em Kotlin: estrutura, módulos, Gradle e organização de pastas

Capítulo 2

Tempo estimado de leitura: 9 minutos

+ Exercício

Anatomia de um projeto Android no Android Studio

Um projeto Android moderno em Kotlin é composto por arquivos de configuração (Gradle) e por um ou mais módulos. O módulo mais comum é o app, que gera o APK/AAB instalável. Entender onde cada coisa fica ajuda a configurar o projeto corretamente, adicionar dependências e manter o código organizado conforme o app cresce.

Estrutura típica (visão geral)

MeuProjeto/  settings.gradle(.kts)  build.gradle(.kts)  gradle.properties  gradle/  libs.versions.toml (opcional)  app/    build.gradle(.kts)    proguard-rules.pro    src/      main/        AndroidManifest.xml        java/ (ou kotlin/)          ...código fonte...        res/          layout/          drawable/          mipmap/          values/          ...        assets/ (opcional)      test/      androidTest/

Módulos: o que é o módulo app e por que ele existe

Módulo é uma unidade de build. Cada módulo pode ter seu próprio build.gradle, dependências e código. Em projetos iniciantes, normalmente você terá apenas:

  • :app: módulo de aplicação (gera o app).

Em projetos maiores, é comum adicionar módulos de biblioteca (ex.: :core, :feature:login) para melhorar organização, reuso e tempo de compilação.

Pastas e arquivos essenciais dentro do módulo app

src/main/AndroidManifest.xml

O Manifest descreve informações essenciais do app: componentes (Activities, Services, Receivers), permissões e configurações globais. Em apps modernos, muitas configurações também vêm do Gradle, mas o Manifest continua sendo central.

Exemplo (simplificado):

Continue em nosso aplicativo e ...
  • Ouça o áudio com a tela desligada
  • Ganhe Certificado após a conclusão
  • + de 5000 cursos para você explorar!
ou continue lendo abaixo...
Download App

Baixar o aplicativo

<manifest package="com.exemplo.meuapp">    <application        android:label="MeuApp"        android:theme="@style/Theme.MeuApp">        <activity android:name=".MainActivity">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>

Observação: em projetos atuais, o atributo package no Manifest pode não ser o “identificador final” do app; o que vale para publicação/instalação é o applicationId definido no Gradle.

src/main/java ou src/main/kotlin

É onde fica o código-fonte. O Android Studio pode mostrar como java mesmo quando você usa Kotlin; isso é apenas uma convenção histórica. O importante é o package do código (ex.: com.exemplo.meuapp), que deve refletir a organização do projeto.

src/main/res

Contém recursos do app (não é código Kotlin):

  • layout/: telas em XML (se você estiver usando Views).
  • drawable/: imagens e shapes.
  • mipmap/: ícones do app.
  • values/: strings, cores, dimensões, temas.
  • navigation/: gráficos de navegação (se usar Navigation).
  • font/: fontes.

Regra importante: nomes de recursos devem ser minúsculos, com underscore (ex.: ic_add, activity_main, color_primary).

src/main/assets (opcional)

Arquivos “crus” que você quer empacotar como estão (ex.: JSON, HTML, modelos). Diferente de res/, assets não recebem IDs gerados em R. Você acessa via assets.open(...).

src/test e src/androidTest

  • test: testes unitários locais (JVM).
  • androidTest: testes instrumentados (rodam em device/emulador).

Gradle: arquivos de build e onde configurar o quê

settings.gradle (ou settings.gradle.kts)

Define o nome do projeto e quais módulos fazem parte dele. Exemplo:

rootProject.name = "MeuProjeto"include(":app")

Também é comum configurar repositórios e o Version Catalog aqui (dependendo do template).

build.gradle do projeto (nível raiz)

Configurações globais: plugins, repositórios (em alguns modelos), e padrões que podem ser compartilhados. Em projetos modernos, a declaração de plugins pode ficar centralizada aqui e aplicada nos módulos.

app/build.gradle (ou app/build.gradle.kts)

É o arquivo mais importante no dia a dia. Nele você define:

  • SDKs (min/target/compile)
  • applicationId, versionCode, versionName
  • buildTypes (debug/release)
  • dependências (AndroidX, Material, etc.)

Exemplo (Groovy) com os pontos principais:

plugins {    id 'com.android.application'    id 'org.jetbrains.kotlin.android'}android {    namespace 'com.exemplo.meuapp'    compileSdk 34    defaultConfig {        applicationId "com.exemplo.meuapp"        minSdk 24        targetSdk 34        versionCode 1        versionName "1.0"        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'        }    }}dependencies {    implementation 'androidx.core:core-ktx:1.12.0'    implementation 'androidx.appcompat:appcompat:1.6.1'    implementation 'com.google.android.material:material:1.11.0'}

Dois campos que geram confusão:

  • namespace: usado pelo Android Gradle Plugin para gerar classes (como R) e organizar recursos. Geralmente deve acompanhar o package do código.
  • applicationId: identificador único do app no dispositivo e na Play Store. Pode ser diferente do namespace (ex.: para flavors), mas no início mantenha igual para evitar confusão.

Version Catalog (libs.versions.toml) quando aplicável

O Version Catalog centraliza versões e coordenadas de dependências, evitando “strings soltas” em vários módulos. Quando existe, você verá um arquivo como:

gradle/libs.versions.toml

Exemplo (simplificado):

[versions]coreKtx = "1.12.0"appcompat = "1.6.1"material = "1.11.0"[libraries]androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "coreKtx" }androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" }google-material = { module = "com.google.android.material:material", version.ref = "material" }

E no dependencies do módulo:

dependencies {    implementation(libs.androidx.core.ktx)    implementation(libs.androidx.appcompat)    implementation(libs.google.material)}

Build variants: debug, release, flavors e o que muda no app

Build variant é uma combinação de:

  • Build type (ex.: debug, release)
  • Product flavor (opcional, ex.: free, paid, dev, prod)

Em projetos iniciantes, você normalmente terá apenas:

  • debug: build para desenvolvimento (pode ter sufixo no appId, logs, etc.).
  • release: build para publicar (otimizações, assinatura, regras de shrink).

Você pode ter código/recursos específicos por variant usando pastas como:

app/src/debug/...app/src/release/...app/src/main/...

applicationId, versionName e versionCode

  • applicationId: identifica o app de forma única. Se mudar, o Android considera outro app (não “atualiza” o anterior).
  • versionCode: número inteiro que deve sempre aumentar a cada release publicada.
  • versionName: texto exibido ao usuário (ex.: 1.0.3).

Exemplo de ajuste por build type (útil para instalar debug e release ao mesmo tempo):

android {  buildTypes {    debug {      applicationIdSuffix ".debug"      versionNameSuffix "-debug"    }  }}

Como adicionar dependências corretamente

Dependências são bibliotecas externas (ou módulos internos) usadas pelo app. Você adiciona no bloco dependencies do módulo que precisa delas (geralmente app).

Tipos comuns de dependência

  • implementation: uso interno no módulo (mais comum).
  • testImplementation: dependências para testes unitários.
  • androidTestImplementation: dependências para testes instrumentados.
  • debugImplementation: só entra no build debug.

Exemplo (Material apenas no debug não faz sentido, mas serve para ilustrar):

dependencies {  debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.13'}

Organização de pastas e pacotes: boas práticas para crescer sem bagunça

Organização é uma decisão de arquitetura. Para iniciantes, duas estratégias comuns são:

1) Por camada (layered)

Boa para apps pequenos e para aprender separação de responsabilidades.

com.exemplo.meuapp  data/    repository/    datasource/    model/  domain/    model/    usecase/  ui/    screen/    components/    viewmodel/  di/  util/
  • Prós: fácil de entender e navegar.
  • Contras: conforme cresce, uma feature pode ficar espalhada em muitas pastas.

2) Por feature (feature-first)

Boa para apps que crescem em funcionalidades independentes.

com.exemplo.meuapp  core/    ui/    data/    util/  feature_login/    ui/    data/    domain/  feature_home/    ui/    data/    domain/
  • Prós: tudo da feature fica junto; facilita manutenção e modularização futura.
  • Contras: exige disciplina para não duplicar coisas que deveriam estar em core.

Padronização de nomes (regras práticas)

  • Packages: minúsculos, sem underscore (ex.: featurelogin ou feature_login não é padrão Java; prefira feature.login como subpackage: feature.login).
  • Classes: PascalCase (ex.: LoginViewModel).
  • Arquivos de layout: snake_case e descritivos (ex.: fragment_login.xml, activity_main.xml).
  • Resources: prefixos ajudam (ex.: ic_ para ícones, bg_ para backgrounds).

Exercício prático: ajustar o projeto (package, SDKs e dependências básicas)

Objetivo: deixar o projeto com identificadores corretos, SDKs configurados e dependências essenciais (AndroidX + Material).

Parte A — Renomear o package/namespace com segurança

Você vai alinhar três coisas: package do código, namespace e applicationId.

  • Escolha um identificador no formato de domínio reverso: com.seunome.meuapp (exemplo).

Passo a passo:

  • No painel de projeto, mude a visualização para Android ou Project.
  • Encontre o package atual em app/src/main/java.
  • Clique com o botão direito no package > Refactor > Rename.
  • Escolha renomear o package (não apenas a pasta) e confirme as alterações.
  • Abra app/build.gradle e ajuste:
    • namespace para o novo package
    • defaultConfig.applicationId para o novo id
  • Verifique o AndroidManifest.xml: se houver referências antigas (ex.: nome fully-qualified de Activity), atualize.
  • Sincronize o Gradle (Sync) e rode o app.

Dica: se você pretende publicar futuramente, evite mudar o applicationId depois que já houver releases distribuídas, pois isso cria um “novo app”.

Parte B — Configurar minSdk e targetSdk

minSdk define a versão mínima do Android suportada. targetSdk indica para qual versão você está “mirando” em termos de comportamento e compatibilidade. compileSdk define com qual SDK você compila.

Passo a passo:

  • Abra app/build.gradle.
  • No bloco android, ajuste para valores coerentes (exemplo):
android {  compileSdk 34  defaultConfig {    minSdk 24    targetSdk 34  }}
  • Sincronize o Gradle.

Observação: escolher minSdk depende do público do app. Para exercícios e apps modernos, minSdk 24 é um ponto de partida comum, mas você pode escolher outro conforme necessidade.

Parte C — Adicionar dependências básicas (AndroidX e Material)

Você vai garantir bibliotecas essenciais para UI e compatibilidade.

Opção 1: sem Version Catalog (strings diretas)

  • No app/build.gradle, adicione/garanta:
dependencies {  implementation 'androidx.core:core-ktx:1.12.0'  implementation 'androidx.appcompat:appcompat:1.6.1'  implementation 'com.google.android.material:material:1.11.0'}

Opção 2: com Version Catalog (libs.versions.toml)

  • No gradle/libs.versions.toml, adicione (ou confirme) entradas para core-ktx, appcompat e material.
  • No app/build.gradle:
dependencies {  implementation(libs.androidx.core.ktx)  implementation(libs.androidx.appcompat)  implementation(libs.google.material)}

Passo final:

  • Sincronize o Gradle.
  • Verifique se o tema do app usa Material (em res/values/themes.xml) e se não há conflitos de versão.

Checklist do exercício

ItemComo validar
Package renomeadoClasses Kotlin estão no novo package e o app compila
namespace ajustadoapp/build.gradle aponta para o novo namespace
applicationId ajustadoInstala como novo app (se mudou) e roda normalmente
SDKs configuradosminSdk/targetSdk/compileSdk definidos e Sync ok
Dependências básicasGradle sincroniza sem erros e Material/AndroidX disponíveis

Agora responda o exercício sobre o conteúdo:

Ao configurar o arquivo app/build.gradle(.kts), qual afirmação descreve corretamente a diferença entre namespace e applicationId?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

O namespace orienta a geração de classes (como R) e a organização de recursos. Já o applicationId é o identificador único do app para instalação e publicação; se ele mudar, o sistema considera outro app.

Próximo capitúlo

Interface Android moderna: layouts, componentes e boas práticas de UI

Arrow Right Icon
Capa do Ebook gratuito Android para Iniciantes com Kotlin: construindo seu primeiro app moderno
13%

Android para Iniciantes com Kotlin: construindo seu primeiro app moderno

Novo curso

15 páginas

Baixe o app para ganhar Certificação grátis e ouvir os cursos em background, mesmo com a tela desligada.