DEV Community

AleMerino-droid
AleMerino-droid

Posted on

Resolviendo el 'Imposible' NoSuchMethodException con Hilt y WorkManager

Una historia de depuración sobre kapt, ksp, y un sutil conflicto de versiones que casi me vuelve loco.


Hola a todos,

Hoy quiero compartir la historia de una batalla de depuración que libré recientemente. Una de esas que te hacen cuestionar todo lo que crees saber sobre tu stack tecnológico. El villano de esta historia es un error que, a primera vista, parece simple: java.lang.NoSuchMethodException.


🧪 El escenario

Estoy refactorizando mi aplicación, DondeEstoySMS, a una arquitectura limpia y modular. Parte de esta refactorización incluye la implementación de un sistema de reintentos robusto para el envío de SMS que fallan, usando WorkManager con Hilt para la inyección de dependencias.

Creé mi HiltWorker, lo anoté correctamente, configuré mis módulos de Hilt... y en tiempo de ejecución, al fallar el primer SMS, la aplicación crasheaba con esto:


Could not instantiate dev.alemerino.dondeestoysms.workers.SmsRetryWorker
java.lang.NoSuchMethodException: \<init\> [class android.content.Context, class androidx.work.WorkerParameters]

Enter fullscreen mode Exit fullscreen mode

🤔 Capítulo 1: Los Sospechosos Habituales

Como en toda buena investigación, empecé por los sospechosos más obvios. Este fue mi checklist inicial:

✅ Check 1: ¿Está la clase Application configurada para Hilt y WorkManager?


@HiltAndroidApp
class DondeEstoySMSApplication : Application(), Configuration.Provider {
    @Inject
    lateinit var workerFactory: HiltWorkerFactory
    override val workManagerConfiguration: Configuration
        get() = Configuration.Builder()
            .setWorkerFactory(workerFactory)
            .build()
}


Enter fullscreen mode Exit fullscreen mode

Y por supuesto, que estuviera declarada en el AndroidManifest.xml:

<application
    android:name=".DondeEstoySMSApplication"
    ...>
</application>
Enter fullscreen mode Exit fullscreen mode

Veredicto: Todo correcto. El error persistía.


✅ Check 2: ¿Está la configuración de kapt en Gradle correcta para Hilt?

plugins {
    id("org.jetbrains.kotlin.kapt")
}

dependencies {
    implementation("androidx.hilt:hilt-work:...")
    kapt("com.google.dagger:hilt-compiler:...")
    kapt("androidx.hilt:hilt-compiler:...") // Para extensiones de AndroidX
}
Enter fullscreen mode Exit fullscreen mode

Veredicto: Después de varios ajustes, la configuración quedó bien. El error... seguía ahí.


✅ Check 3: ¿Están todas las dependencias del Worker provistas por Hilt?

@HiltWorker
class SmsRetryWorker @AssistedInject constructor(
    @Assisted appContext: Context,
    @Assisted workerParams: WorkerParameters,
    private val db: AppDatabase,
    private val smsManager: SmsManager
) : CoroutineWorker(appContext, workerParams) { /* ... */ }
Enter fullscreen mode Exit fullscreen mode

Veredicto: Verifiqué que AppDatabase y SmsManager estaban bien provistos con @Provides. Todo correcto. La frustración aumentaba.


💡 Capítulo 2: El Hallazgo Clave

Cuando el código parece perfecto pero el crash persiste, la causa suele estar en el entorno de compilación. Con ayuda de mi asistente de IA, decidí revisar mi gradle/libs.versions.toml.

Y ahí estaba el conflicto.

Librería Versión usada Diagnóstico
Dagger Hilt 2.51.1 ✅ OK
AndroidX Hilt 1.2.0 🚨 Incompatible

🔧 Capítulo 3: La Solución Definitiva

La versión 1.2.0 de androidx.hilt está pensada para KSP, mientras que mi proyecto, para asegurar la compatibilidad total de Hilt, seguía usando kapt. Esto causaba un fallo silencioso: no se generaba la clase HiltSmsRetryWorker_Factory, y por eso el Worker no se instanciaba.

La solución fue alinear versiones, cambiando una sola línea en gradle/libs.versions.toml:

# Antes:
hiltAndroidx = "1.2.0"

# Después:
hiltAndroidx = "1.1.0"
Enter fullscreen mode Exit fullscreen mode

Sync Now → Clean & Rebuild → Modo avión → Activar SOS → Desactivar avión…
Y en Logcat apareció la frase mágica:

I/SmsRetryWorker: Iniciando trabajo de reintento de SMS.
Enter fullscreen mode Exit fullscreen mode

🧠 Conclusión

En el desarrollo moderno de Android, los bugs más “imposibles” no siempre son errores de lógica. Muchas veces son sutiles conflictos de versión, silencios del compilador, o incompatibilidades entre herramientas que avanzan más rápido que la documentación.

Si estás seguro de tu código, revisa tus versiones. Abre tu libs.versions.toml y míralo con lupa. Porque a veces… la respuesta está en cambiar un simple 1.2.0 por un confiable 1.1.0.

Espero que mi odisea te ahorre unas cuantas horas de frustración.

¡Feliz coding!


Sobre el Autor

👨‍💻 Alejandro Merino

Desarrollador Android enfocado en crear soluciones con propósito social, compatibilidad extendida y arquitectura moderna. Me apasiona construir aplicaciones que realmente resuelven problemas concretos, especialmente en contextos vulnerables.

🧰 Tecnologías que uso

  • Kotlin · Jetpack Compose · Coroutines
  • Hilt · WorkManager · Room · DataStore
  • Retrofit · Firebase · Gradle · Git

🧠 Filosofía como desarrollador

  • Diagnóstico primero: cada bug es una oportunidad para aprender.
  • Código que se deja mantener: porque el futuro también importa.
  • Tecnología empática: soluciones pensadas para personas reales.

🌐 Presencia técnica

Top comments (0)