O que muda no build de release (debug vs release)
No Android, você normalmente compila o app em dois “modos” principais: debug (para desenvolvimento) e release (para distribuição). Eles diferem em assinatura, otimizações e no que é permitido no pacote final.
| Aspecto | Debug | Release |
|---|---|---|
| Assinatura | Automática com debug keystore do Android Studio | Obrigatória com sua keystore (chave privada do app) |
| Otimizações | Menos otimizações, build mais rápido | Otimizações e possibilidade de minificação/obfuscação (R8) |
| Logs e diagnósticos | Mais permissivo (ex.: logs detalhados) | Deve evitar logs sensíveis e debug flags |
| Distribuição | Instalação local e testes | Play Console e distribuição para usuários |
O objetivo do release é gerar um pacote assinado, com versionamento correto, tamanho/performance melhores e sem informações sensíveis.
APK vs AAB: qual gerar?
APK é o pacote instalável tradicional. AAB (Android App Bundle) é o formato recomendado para publicação na Google Play: você envia um AAB e a loja gera APKs otimizados por dispositivo (ABI, densidade, idioma), reduzindo o download.
- Para publicar na Play: prefira AAB.
- Para instalar manualmente/localmente: APK é mais direto (embora seja possível testar AAB via bundletool).
Keystore e assinatura: criando e guardando sua chave
Para release, o app precisa ser assinado com uma chave privada. Essa chave define a “identidade” do app. Se você perder a chave, pode ficar impedido de atualizar o app (dependendo do setup de assinatura).
Criar uma keystore no Android Studio (passo a passo)
- No Android Studio, vá em Build > Generate Signed Bundle / APK…
- Escolha Android App Bundle (ou APK, se necessário) e clique em Next.
- Em Key store path, clique em Create new…
- Preencha:
- Key store path: local seguro (idealmente fora do projeto)
- Password e Confirm: senha forte
- Key alias: um nome para a chave
- Key password: pode ser igual à senha da keystore
- Validity (years): use um período longo (ex.: 25+ anos)
- Dados do certificado (CN, OU, O, L, ST, C)
- Salve e avance. O Android Studio usará essa keystore para assinar o bundle.
Cuidados essenciais com a keystore
- Não commitar a keystore no Git.
- Faça backup (ex.: cofre de senhas/armazenamento seguro corporativo).
- Guarde também: senhas, alias e o caminho do arquivo.
- Evite colocar a keystore dentro da pasta do projeto para reduzir risco de vazamento.
Configurando assinatura no Gradle (sem expor segredos)
Você pode assinar via assistente do Android Studio, mas em times e CI é comum configurar no Gradle. O ponto crítico é: não deixar senha em texto puro no repositório.
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
Baixar o aplicativo
Opção prática: usar keystore.properties (não versionado)
Crie um arquivo keystore.properties na raiz do projeto (mesmo nível do settings.gradle) e adicione ao .gitignore.
storeFile=/caminho/seguro/minha-release.keystore
storePassword=MINHA_SENHA
keyAlias=meu_alias
keyPassword=MINHA_SENHA_DA_CHAVENo app/build.gradle.kts, carregue essas propriedades e configure o signingConfig:
import java.util.Properties
val keystorePropsFile = rootProject.file("keystore.properties")
val keystoreProps = Properties().apply {
if (keystorePropsFile.exists()) {
load(keystorePropsFile.inputStream())
}
}
android {
signingConfigs {
create("release") {
val storeFilePath = keystoreProps["storeFile"] as String?
if (storeFilePath != null) {
storeFile = file(storeFilePath)
storePassword = keystoreProps["storePassword"] as String
keyAlias = keystoreProps["keyAlias"] as String
keyPassword = keystoreProps["keyPassword"] as String
}
}
}
buildTypes {
getByName("release") {
signingConfig = signingConfigs.getByName("release")
}
}
}Em CI, você pode gerar esse arquivo dinamicamente com variáveis de ambiente, ou configurar diretamente via secrets do provedor.
Versionamento: versionCode e versionName
O Android usa dois campos principais:
- versionCode: inteiro que sempre aumenta a cada release. A Play usa isso para decidir se uma atualização é mais nova.
- versionName: string exibida ao usuário (ex.:
1.4.2).
Em projetos modernos, isso fica no defaultConfig do módulo app. Exemplo (pode variar conforme template):
android {
defaultConfig {
versionCode = 12
versionName = "1.2.0"
}
}Estratégias simples para versionCode
- Incremental: 1, 2, 3… (mais simples).
- Semântico codificado: por exemplo,
MMmmpp(major/minor/patch) em inteiro: 10203 para 1.2.3. Exige disciplina para não “voltar” número.
Regra de ouro: nunca reutilize um versionCode já publicado.
Build Types: configurando debug e release
Build types permitem comportamentos diferentes por variante. Em release, você normalmente quer:
- Minificação/obfuscação (opcional, mas comum)
- Remover logs sensíveis
- Desabilitar flags de debug
- Assinatura de release
Exemplo de configuração típica:
android {
buildTypes {
getByName("debug") {
applicationIdSuffix = ".debug"
versionNameSuffix = "-debug"
isDebuggable = true
}
getByName("release") {
isDebuggable = false
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
}applicationIdSuffix no debug ajuda a instalar debug e release ao mesmo tempo no dispositivo (IDs diferentes).
Minificação com R8: noções e cuidados
O R8 pode:
- Minificar (remover código não usado)
- Obfuscar (renomear classes/métodos para reduzir e dificultar engenharia reversa)
- Otimizar (algumas otimizações de bytecode)
Riscos comuns ao ativar minificação
- Bibliotecas que usam reflection (ex.: serialização) podem quebrar se classes forem removidas/renomeadas.
- Modelos usados por frameworks podem precisar de keep rules.
- Crashes podem ficar mais difíceis de ler sem mapeamento.
Regras de keep (exemplo)
Se você perceber que algo “sumiu” no release, pode ser necessário manter classes. Exemplo genérico em proguard-rules.pro:
# Exemplo: manter classes de um pacote usado via reflection
-keep class com.seuapp.models.** { *; }
# Manter anotações (útil para algumas libs)
-keepattributes *Annotation*Evite adicionar regras amplas demais (como manter tudo), porque isso reduz o ganho de minificação.
Mapeamento (mapping.txt)
Quando há obfuscação, o build gera um arquivo de mapeamento que permite “desofuscar” stacktraces. Guarde o mapping.txt de cada versão publicada (ele fica nos outputs do build). Isso é essencial para investigar crashes em produção.
Removendo logs sensíveis e flags de debug
Antes de publicar, revise o que o app imprime em log e o que expõe em erros. Boas práticas:
- Evite logar: tokens, headers de autenticação, dados pessoais, payloads completos.
- Desabilite logs verbosos em release.
- Garanta que endpoints de teste/dev não sejam usados em release.
Padrão simples: log apenas em debug
Use a flag BuildConfig.DEBUG para condicionar logs:
if (BuildConfig.DEBUG) {
android.util.Log.d("Auth", "Resposta: $response")
}Para algo mais organizado, crie um wrapper:
object AppLog {
fun d(tag: String, msg: String) {
if (BuildConfig.DEBUG) android.util.Log.d(tag, msg)
}
}Assim você centraliza a política de logs e reduz risco de esquecer logs sensíveis.
Gerando APK/AAB assinado (passo a passo)
Gerar AAB assinado pelo Android Studio
- Abra o projeto no Android Studio.
- Vá em Build > Generate Signed Bundle / APK…
- Selecione Android App Bundle e clique em Next.
- Selecione sua keystore, informe password, alias e key password.
- Escolha o Build Variant como release.
- Confirme e gere. O Android Studio mostrará o caminho do arquivo
.aab.
Gerar via Gradle (útil para automação)
Na janela do Terminal do Android Studio:
./gradlew :app:bundleReleaseO AAB costuma ser gerado em um caminho semelhante a:
app/build/outputs/bundle/release/app-release.aabPara APK:
./gradlew :app:assembleReleasePreparando o app para publicação: itens que você precisa revisar
Ícone, nome e identidade do app
- Ícone adaptativo: verifique se existe ícone para diferentes densidades e se o adaptativo está correto (foreground/background).
- Nome do app: revise o
label(nome exibido no launcher) e se está adequado para o idioma principal. - Package name (applicationId): não deve mudar após publicado (mudanças exigem novo app na loja).
Permissões declaradas
Mesmo que você já tenha implementado permissões corretamente, para release é importante revisar o AndroidManifest.xml e remover permissões não usadas. Permissões desnecessárias:
- Reduzem confiança do usuário
- Podem exigir justificativas adicionais na loja
- Podem bloquear publicação em alguns cenários
Checklist rápido:
- Existe alguma permissão que não é mais usada?
- Alguma permissão “sensível” está declarada sem necessidade?
- O app funciona sem pedir permissões que não são essenciais?
Privacidade e dados
Antes de publicar, tenha clareza sobre:
- Quais dados o app coleta (conta, localização, identificadores, etc.)
- Para que finalidade (funcionalidade, analytics, suporte)
- Onde isso é informado ao usuário (política de privacidade, telas do app)
Mesmo em apps simples, é comum precisar de uma política de privacidade se houver coleta de dados, analytics ou login.
Checklist técnico de release (rápido e objetivo)
- Telas principais: abrir/fechar app, navegação básica, estados vazios e erro.
- Crashes: rode o app em release e execute o fluxo principal completo.
- Performance básica: tempo de abertura aceitável, sem travamentos óbvios, listas sem engasgos.
- Rede: modo avião/sem internet (mensagens adequadas, sem loop infinito).
- Rotação e background: volte do background e verifique se o estado essencial se mantém.
- Dados sensíveis: nenhum token/segredo em logs, nenhum endpoint de teste.
- Minificação: se ativada, validar fluxos que usam reflection/serialização.
Prática final: gerar um AAB assinado e validar a instalação no dispositivo
1) Gere o AAB assinado (release)
- Confirme no
build.gradle.ktsque o build typereleaseestá configurado (assinatura e, se desejar, minificação). - Gere o bundle: Build > Generate Signed Bundle / APK… > Android App Bundle.
- Guarde o arquivo
app-release.aabem uma pasta de releases do projeto (fora do repositório, se contiver artefatos sensíveis).
2) Valide no dispositivo: instalando um APK de release (método mais simples)
Como AAB não é instalado diretamente no Android sem ferramentas, a validação local mais simples é gerar também um APK release assinado e instalar no dispositivo.
- Gere o APK assinado: Build > Generate Signed Bundle / APK… > APK (release).
- No dispositivo, habilite instalação via USB (opções de desenvolvedor) e conecte ao computador.
- Instale via ADB:
adb install -r app-release.apkAbra o app e execute o checklist técnico (fluxo principal, rede, telas, sem crashes).
3) Valide o AAB localmente (opcional, mais fiel ao que a Play faz)
Para testar o AAB como bundle (gerando APKs por dispositivo), use o bundletool. Fluxo típico:
- Baixe o bundletool (arquivo
.jar). - Gere um arquivo de APKs a partir do AAB:
java -jar bundletool.jar build-apks --bundle=app-release.aab --output=app-release.apks --ks=/caminho/minha-release.keystore --ks-key-alias=meu_alias- Instale no dispositivo conectado:
java -jar bundletool.jar install-apks --apks=app-release.apksSe a instalação falhar, revise: assinatura, versionCode (não pode ser menor que o instalado), e regras de minificação (se houver crash apenas em release).