📚 Pré-requisitos Teóricos: este projeto aplica conceitos ensinados na Especialização em Android Nativo. Recomendado revisar antes de iniciar.
v1.0 — Android Nativo, Kotlin, Retrofit 2, Moshi, OkHttp Interceptors, Consumo de APIs REST e Carregamento Assíncrono com Glide
Série Prática Android Clássico — Projeto 7 de 21
- P06: Catálogo Offline com Room Database & Coroutines
- ➡️ P07 (este): Master Pokédex com Retrofit 2 & REST API
- P08: Batalha Scanner com CameraX & QR Code
- P09: PokeMap com Google Maps & GPS
- P10: Arena Social com Firebase Suite
O projeto Master Pokédex implementa o consumo corporativo de APIs RESTful na plataforma Android utilizando o padrão de ouro da indústria: Retrofit 2 integrado ao cliente HTTP OkHttp. A aplicação realiza requisições assíncronas para a PokéAPI pública, desserializa payloads JSON complexos com segurança de tipos via Moshi, intercepta requisições para telemetria de rede com HttpLoggingInterceptor e renderiza sprites em alta resolução com a biblioteca de imagem Glide.
Todos os clientes HTTP, contratos de serviço, DTOs e telas residem na subpasta canônica mobile-android-kotlin/:
catalogo_projetos/android_p07_pokedex_retrofit/
├── assets/
│ └── arquitetura_pokedex_retrofit.svg
├── mobile-android-kotlin/
│ ├── app/
│ │ ├── src/
│ │ │ └── main/
│ │ │ ├── java/br/com/curso/pokedex/
│ │ │ │ ├── api/
│ │ │ │ │ ├── PokeApiService.kt
│ │ │ │ │ └── RetrofitClient.kt
│ │ │ │ ├── model/
│ │ │ │ │ └── PokemonResponse.kt
│ │ │ │ └── MainActivity.kt
│ │ │ └── res/
│ │ └── build.gradle
│ ├── gradle/
│ ├── build.gradle
│ ├── gradlew
│ ├── settings.gradle
│ └── README.md
└── index.md
| ID | Persona | Narrativa da Funcionalidade | Critério de Aceitação Principal | Prioridade |
|---|---|---|---|---|
| US-01 | Treinador Pokémon | Quero buscar um Pokémon pelo número da Pokédex ou nome. | Retorno das informações oficiais da PokéAPI e exibição da ficha completa. | Alta |
| US-02 | Treinador Pokémon | Quero visualizar o sprite oficial animado e as barras de estatísticas de combate (HP, Ataque, Defesa). | Renderização assíncrona da imagem via Glide com indicador de carregamento. | Alta |
| US-03 | Treinador Pokémon | Quero receber aviso amigável caso pesquise um número inexistente ou a conexão falhe. | Feedback visual claro na tela sem travamento (crash) do app. | Alta |
| US-04 | Desenvolvedor Mobile | Quero inspecionar os cabeçalhos e respostas HTTP no Logcat durante o desenvolvimento. | Log estruturado habilitado via HttpLoggingInterceptor. |
Média |
| US-05 | Engenheiro de QA | Quero testar o cliente Retrofit contra respostas simuladas (MockWebServer). | Testes unitários com fixtures JSON mockados sem bater na rede real. | Baixa |
PokeApiService com método anotado @GET("pokemon/{id}").MoshiConverterFactory.OkHttpClient.Glide.with(context).load(url).Dispatchers.IO sem congelar a tela.flowchart TD
User([fa:fa-user Treinador])
API[(fa:fa-cloud PokéAPI REST)]
subgraph AppPokedex ["☁️ Master Pokédex (mobile-android-kotlin)"]
UC01["Pesquisar Pokémon por Nome/ID"]
UC02["Disparar Requisição REST Retrofit"]
UC03["Desserializar Payload com Moshi"]
UC04["Baixar e Exibir Sprite via Glide"]
UC05["Tratar Falhas de Conectividade"]
end
User --> UC01
UC01 --> UC02
UC02 --> API
API -.->|JSON| UC03
UC03 --> UC04
UC02 -.->|Falha/Timeout| UC05
| ID Requisito | História de Usuário | Artefato de Código | Teste de Aceitação |
|---|---|---|---|
| RF-01 | US-01 | mobile-android-kotlin/app/.../PokeApiService.kt |
testPokeApiServiceContract() |
| RF-02 | US-01 | mobile-android-kotlin/app/.../PokemonResponse.kt |
testMoshiJsonDeserialization() |
| RF-03 | US-04 | mobile-android-kotlin/app/.../RetrofitClient.kt |
testOkHttpClientConfiguration() |
| RF-04 | US-02 | mobile-android-kotlin/app/.../MainActivity.kt |
testGlideImageLoadingNotNull() |
| RF-05 | US-03 | mobile-android-kotlin/app/.../MainActivity.kt |
testCoroutineCancellationOnDestroy() |
PokeApi.kt)📄 mobile-android-kotlin/app/src/main/java/br/com/curso/masterpokedex/data/network/PokeApi.kt (arquivo real do projeto)
package br.com.curso.masterpokedex.data.network
import com.google.gson.annotations.SerializedName
import retrofit2.http.GET
import retrofit2.http.Path
// 1. MODELOS DE DADOS (Dicionário da API)
data class PokemonListResponse(
val results: List<PokemonBrief>
)
data class PokemonBrief(
val name: String,
val url: String
)
data class PokemonDetailResponse(
val id: Int,
val name: String,
@SerializedName("sprites") val sprites: SpriteResponse
)
data class SpriteResponse(
@SerializedName("front_default") val frontDefault: String
)
// 2. O GARÇOM (Retrofit Interface)
interface PokeApiService {
@GET("pokemon?limit=20")
suspend fun getList(): PokemonListResponse
@GET("pokemon/{name}")
suspend fun getDetail(@Path("name") name: String): PokemonDetailResponse
}
cd catalogo_projetos/android_p07_pokedex_retrofit/mobile-android-kotlin
./gradlew assembleDebug
./gradlew test
| Checkpoint | Meta Técnica | Critério de Aceite | Status |
|---|---|---|---|
| CP-01 | Configuração Retrofit 2 | Instância configurada com baseUrl e MoshiConverter | PASS ✅ |
| CP-02 | Consumo de API Real | Obtenção bem-sucedida de dados de monstros via PokéAPI | PASS ✅ |
| CP-03 | Carregamento de Imagem | Glide baixando sprites e gerenciando placeholders visuais | PASS ✅ |
| CP-04 | Tratamento de Exceções HTTP | Falhas de rede tratadas sem fechamento inesperado do app | PASS ✅ |
| CP-05 | Suíte de Testes Automatizados | Testes de unidade aprovados com MockWebServer | PASS ✅ |