Injecao de dependencias no Android: Hilt vs Koin - Guia completo e perguntas de entrevista 2026
Comparacao entre Hilt e Koin para injecao de dependencias no Android com exemplos de codigo, benchmarks de desempenho e perguntas de entrevista. Hilt 2.60, Koin 4.2.

A injecao de dependencias determina como as classes recebem suas dependencias em vez de cria-las diretamente. No ecossistema Android de 2026, dois frameworks dominam o cenario: Hilt (a solucao compile-time do Google construida sobre o Dagger) na versao 2.60.1, e Koin (um service locator leve que opera em tempo de execucao) na versao 4.2.2. A escolha entre ambos afeta tempos de compilacao, desempenho na inicializacao, testabilidade e a velocidade com que novos desenvolvedores sao integrados ao time.
O Hilt valida todo o grafo de dependencias durante a compilacao e falha o build caso alguma vinculacao esteja ausente. O Koin resolve dependencias em tempo de execucao usando um DSL Kotlin, capturando erros de configuracao apenas quando o caminho de codigo afetado e executado. Essa diferenca fundamental determina todos os trade-offs entre os dois frameworks.
Como o Hilt funciona internamente
O Hilt gera componentes Dagger mapeados para classes do ciclo de vida do Android. A anotacao @HiltAndroidApp dispara a geracao de codigo em tempo de compilacao, produzindo factories e providers para cada vinculacao declarada. O KSP (Kotlin Symbol Processing) substituiu o KAPT como processador de anotacoes recomendado a partir do Hilt 2.48, reduzindo o tempo de processamento pela metade.
Uma configuracao tipica do Hilt envolve tres pecas: um modulo declarando as vinculacoes, um ponto de entrada (Activity, Fragment ou ViewModel) e a classe Application anotada com @HiltAndroidApp.
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
@Singleton
fun provideRetrofit(): Retrofit {
return Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
}
@Provides
@Singleton
fun provideUserRepository(
retrofit: Retrofit
): UserRepository {
return UserRepositoryImpl(retrofit.create(UserApi::class.java))
}
}@HiltViewModel
class UserViewModel @Inject constructor(
private val userRepository: UserRepository
) : ViewModel() {
private val _users = MutableStateFlow<List<User>>(emptyList())
val users: StateFlow<List<User>> = _users.asStateFlow()
fun loadUsers() {
viewModelScope.launch {
_users.value = userRepository.getUsers()
}
}
}O compilador verifica que UserRepository possui um provider valido antes mesmo da aplicacao ser executada. Vinculacoes ausentes se manifestam como erros de compilacao, nao como crashes em producao.
Configuracao do Koin e a abordagem DSL Kotlin
O Koin segue a direcao oposta: zero geracao de codigo, zero processamento de anotacoes. As dependencias sao declaradas em Kotlin puro usando um DSL, e o framework as resolve em tempo de execucao por meio de um registro global de servicos. O Koin 4.2 introduziu modulos lazy para carregamento paralelo na inicializacao e o motor CoreResolverV2 que otimiza a resolucao de escopos.
val appModule = module {
// Singleton Retrofit instance
single<Retrofit> {
Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
}
// Singleton repository bound to its interface
single<UserRepository> {
UserRepositoryImpl(get<Retrofit>().create(UserApi::class.java))
}
// ViewModel with injected repository
viewModel { UserViewModel(get()) }
}class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
startKoin {
androidContext(this@MyApplication)
modules(appModule)
}
}
}O DSL e lido de forma natural e nao requer nenhum plugin de processamento de anotacoes na configuracao do Gradle. O custo: um erro de digitacao na resolucao get() so aparece em tempo de execucao quando o ponto de injecao afetado e acionado.
Benchmarks de desempenho: tempo de build vs custo em runtime
A questao do desempenho aparece em praticamente toda entrevista tecnica Android. Numeros concretos valem mais do que opinioes.
| Metrica | Hilt 2.60 (KSP) | Koin 4.2 |
|---|---|---|
| Overhead build limpo | +8-15s (geracao KSP) | ~0s (sem geracao) |
| Overhead build incremental | +2-4s | ~0s |
| Inicializacao app (50 bindings) | ~0ms (codigo pre-gerado) | ~5-15ms (resolucao do grafo) |
| Inicializacao app (500 bindings) | ~0ms | ~30-80ms |
| Impacto no tamanho do APK | +200-400 KB (codigo gerado) | +100 KB (biblioteca runtime) |
| Deteccao de vinculacao ausente | Erro de compilacao | Crash em runtime |
| SDK minimo requerido | API 23 | API 23 |
Para projetos com menos de 100 bindings, o overhead de runtime do Koin permanece imperceptivel. Acima de 300 bindings, o custo na inicializacao se torna mensuravel, embora os modulos lazy do Koin 4.2 mitiguem isso ao paralelizar o carregamento dos modulos.
O Dagger 2.60 removeu o suporte multidex e passou a exigir minSDK 23, alinhando-se aos requisitos do AndroidX. Projetos que visam API 21-22 nao podem mais usar o Hilt. Esta versao tambem requer AGP 9 e Gradle 9.1+ ao usar o plugin Gradle do Hilt.
Estrategias de teste com cada framework
A testabilidade e onde as diferencas arquiteturais se tornam praticas. O Hilt oferece @TestInstallIn para substituir modulos de producao por test doubles em tempo de compilacao. O Koin disponibiliza loadKoinModules() para sobreescrever definicoes em tempo de execucao.
// Hilt test module — replaces AppModule bindings in tests
@Module
@TestInstallIn(
components = [SingletonComponent::class],
replaces = [AppModule::class]
)
object FakeAppModule {
@Provides
@Singleton
fun provideUserRepository(): UserRepository {
return FakeUserRepository() // In-memory test double
}
}// Koin test — override at runtime
class UserViewModelTest : KoinTest {
@Before
fun setUp() {
startKoin {
modules(
module {
single<UserRepository> { FakeUserRepository() }
viewModel { UserViewModel(get()) }
}
)
}
}
@Test
fun `loads users from repository`() {
val viewModel: UserViewModel = get()
viewModel.loadUsers()
assertEquals(3, viewModel.users.value.size)
}
@After
fun tearDown() {
stopKoin()
}
}Os testes com Hilt detectam modulos de teste mal configurados em tempo de compilacao. Os testes com Koin exigem gerenciamento cuidadoso do ciclo de vida (startKoin/stopKoin), mas oferecem mais flexibilidade para sobrecargas parciais de modulos.
Pronto para mandar bem nas entrevistas de Android?
Pratique com nossos simuladores interativos, flashcards e testes tecnicos.
Arquitetura multi-modulo: escalando DI entre features
Projetos Android de grande porte distribuem funcionalidades em modulos Gradle separados. O framework de DI precisa lidar com as fronteiras entre modulos de forma limpa. Ambos os frameworks se integram naturalmente com os padroes de modularizacao Android moderna.
Com o Hilt, cada modulo de feature declara seu proprio @Module anotado com @InstallIn. O Hilt mescla todos os modulos em uma hierarquia unica de componentes em tempo de compilacao. A arquitetura MVVM combina naturalmente com os componentes com escopo do Hilt.
@Module
@InstallIn(ViewModelComponent::class)
object PaymentModule {
@Provides
fun providePaymentGateway(
retrofit: Retrofit // Provided by :app module
): PaymentGateway {
return StripePaymentGateway(retrofit.create(PaymentApi::class.java))
}
}Com o Koin, os modulos de feature exportam suas declaracoes module {}, e o modulo da aplicacao carrega todos na inicializacao. Os modulos lazy do Koin 4.2 permitem carregamento adiado dos modulos de feature ate o primeiro acesso.
val paymentModule = module {
factory<PaymentGateway> {
StripePaymentGateway(get<Retrofit>().create(PaymentApi::class.java))
}
}
// app/MyApplication.kt — loads all feature modules
startKoin {
modules(appModule, paymentModule, analyticsModule)
}O Hilt impoe a visibilidade das dependencias por meio dos escopos de componentes. O Koin se baseia em convencoes: qualquer modulo pode acessar as definicoes de qualquer outro modulo, o que proporciona flexibilidade, mas pode gerar acoplamento implicito.
Consideracoes sobre Kotlin Multiplatform
O Koin suporta Kotlin Multiplatform (KMP) nativamente. O mesmo DSL module {} funciona no Android, iOS, Desktop e alvos Web. O Hilt e exclusivo do Android, pois depende de componentes de ciclo de vida especificos da plataforma e do processador de anotacoes do Dagger.
Para projetos que visam multiplas plataformas, o Koin e a unica opcao viavel entre os dois. Modulos de logica de negocio compartilhada podem declarar suas dependencias uma unica vez e injeta-las em todos os alvos.
Migracao entre frameworks
O Koin 4.2 introduziu um modulo ponte Dagger que permite uma migracao gradual. Times que estao migrando do Hilt para o Koin podem expor os modulos Dagger existentes atraves do service locator do Koin durante a transicao. Essa abordagem incremental evita uma reescrita completa, mas adiciona complexidade temporaria.
Perguntas frequentes de entrevista sobre DI no Android
Estas perguntas aparecem regularmente em entrevistas tecnicas Android. Cada resposta se mantem concisa e foca no que os entrevistadores esperam.
P: Qual e a diferenca entre injecao de dependencias em compile-time e runtime?
A injecao em compile-time (Hilt/Dagger) gera o codigo de injecao durante o build. O compilador valida todo o grafo de dependencias, capturando vinculacoes ausentes antes da execucao. A injecao em runtime (Koin) resolve dependencias quando sao solicitadas pela primeira vez, utilizando um padrao de registro de servicos. A injecao em compile-time produz uma inicializacao mais rapida, porem builds mais lentos; a injecao em runtime nao impacta o build, mas adia a deteccao de erros.
P: Quais escopos de componentes Hilt existem e como se mapeiam aos ciclos de vida do Android?
SingletonComponent persiste durante toda a vida da aplicacao. ActivityRetainedComponent sobrevive a mudancas de configuracao. ViewModelComponent tem escopo vinculado ao ciclo de vida de um ViewModel. ActivityComponent, FragmentComponent e ViewComponent seguem seus respectivos lifecycle owners do Android. Escopos personalizados podem estender essa hierarquia.
P: Como o Koin lida com a injecao de ViewModel no Jetpack Compose?
O Koin fornece koinViewModel() como funcao Composable que cria ou recupera um ViewModel com escopo no ViewModelStoreOwner mais proximo. Desde o Koin 4.2, koinNavViewModel() vincula o escopo dos ViewModels as entradas do grafo de navegacao ao usar a navegacao do Jetpack Compose. O Koin 4.2 tambem adicionou suporte nativo para o Jetpack Navigation 3.
P: Em quais situacoes o Koin seria uma escolha melhor do que o Hilt?
O Koin se encaixa melhor em projetos KMP (o Hilt e exclusivo do Android), aplicacoes de pequeno a medio porte onde o tempo de build importa mais que o tempo de inicializacao, e equipes que preferem um DSL Kotlin explicito em vez de configuracao baseada em anotacoes. Prototipos e provas de conceito tambem se beneficiam da configuracao minima do Koin.
Chamar o Koin de "framework de injecao de dependencias" e tecnicamente impreciso. O Koin e um service locator: as dependencias sao obtidas via get() em vez de injetadas via construtor. Entrevistadores familiarizados com essa distincao esperam que os candidatos a reconhecam. Hilt/Dagger realiza verdadeira injecao de dependencias por meio de chamadas a construtores geradas.
Framework de decisao: escolhendo entre Hilt e Koin
| Fator | Hilt | Koin |
|---|---|---|
| Validacao do grafo | Compile-time | Runtime |
| Impacto no tempo de build | Maior (codegen KSP) | Nenhum |
| Custo de inicializacao | Quase zero | Escala com o tamanho do grafo |
| Curva de aprendizado | Mais ingreme (conceitos Dagger) | Suave (DSL Kotlin puro) |
| Suporte KMP | Nao | Sim |
| Integracao Jetpack | Profunda (Google oficial) | Boa (comunidade + Navigation 3) |
| Escalabilidade do time | Mais solida (escopos impostos) | Flexivel (baseada em convencoes) |
| Testes | @TestInstallIn (compile-safe) | loadKoinModules (runtime) |
| SDK minimo | API 23 (desde 2.60) | API 23 |
Nenhum dos frameworks e universalmente superior. A escolha depende do tamanho do projeto, da experiencia do time e das plataformas-alvo.
Comece a praticar!
Teste seus conhecimentos com nossos simuladores de entrevista e testes tecnicos.
Fontes
- Notas de versao Dagger 2.60: requisito minSDK 23, @Binds sem parametros, suporte AGP 9
- Notas de versao Koin 4.2: CoreResolverV2, ponte Dagger, suporte Navigation 3
- Documentacao de integracao Dagger no Koin: modulo ponte para migracao gradual
Pontos-chave sobre Hilt vs Koin
- O Hilt 2.60 com KSP entrega validacao do grafo em compile-time e custo de inicializacao quase zero, mas agora exige minSDK 23 e AGP 9+, posicionando-se como a escolha mais solida para grandes projetos Android de plataforma unica com requisitos rigorosos de confiabilidade
- O Koin 4.2 com modulos lazy,
CoreResolverV2e a nova ponte Dagger reduz a diferenca de desempenho na inicializacao enquanto mantem zero impacto no build e compatibilidade completa com KMP - Ambos os frameworks lidam com arquiteturas multi-modulo, mas o Hilt impoe limites de escopo em compile-time enquanto o Koin depende de convencoes do time
- Para a preparacao para entrevistas Android, entender o trade-off entre compile-time e runtime e saber articular quando cada framework se encaixa melhor e a base esperada
- Migrar entre frameworks nao e trivial, mas a ponte Dagger do Koin agora oferece uma via incremental para times que estao abandonando o Hilt
Você saberia encontrar o bug em Android?
Um trecho real, um bug escondido, uma tentativa por dia. Sem conta para testar.

Escrito por
Anthony Fillion-MailletFundador da SharpSkill
Desenvolvedor fullstack há mais de 10 anos. Dirige a SharpSkill e responde por tudo o que é publicado aqui.
Atualizado em 27 de setembro de 2026
Tags
Compartilhar
Artigos relacionados

Modularização Android em 2026: Arquitetura Multi-Módulo e Perguntas de Entrevista
Guia completo sobre modularização Android em 2026. Aprenda a estruturar uma arquitetura multi-módulo, usar catálogos de versões Gradle e dominar as perguntas essenciais de entrevista técnica.

Android WorkManager em 2026: Tarefas em Segundo Plano, Restrições e Perguntas de Entrevista
Guia completo sobre WorkManager para Android em 2026: criação de Workers, restrições de execução, encadeamento de tarefas e perguntas técnicas de entrevista.

Kotlin Flow vs StateFlow vs SharedFlow: perguntas de entrevista Android em 2026
As perguntas sobre Kotlin Flow vs StateFlow vs SharedFlow que os entrevistadores de Android fazem em 2026, com respostas claras, tabela comparativa e código pronto para produção.