StackOverflowError on Android API 19 and lower
See original GitHub issueI have an Android project that is using KoDeIn 5.0.0.
In the project, there are these files:
interface GemCache {
...
}
class GemCacheImpl(context: Context, id: Int) : GemCache {
...
}
interface GemRepository {
...
}
class GemRepositoryImpl(private val cache: GemCache) : GemRepository {
...
}
class FindGemUseCase(
private val repository: GemRepository,
private val threadExecutor: Scheduler,
private val postExecutionThread: Scheduler
) {
...
}
class GemViewModel(private val findGemUseCase: FindGemUseCase) : ViewModel() {
...
}
class ViewModelFactory(
private val creators: Map<Class<out ViewModel>, ViewModel>
) : ViewModelProvider.Factory {
...
}
Basically, the dependency graph is quite clear
ViewModelFactory
-> Map<Class<out ViewModel>, ViewModel>
Map<Class<out ViewModel>, ViewModel>
contains Pair(GemViewModel::class.java, GemViewModel)
GemViewModel
-> FindGemUseCase
-> GemRepository
-> gemCache
-> Context
So I defined these modules
val cacheModule: Kodein.Module = Kodein.Module {
bind<GemCache>() with provider {
GemCacheImpl(instance(), instance(tag = "resourceId"))
}
}
val dataModule: Kodein.Module = Kodein.Module {
bind<GemRepository>() with provider {
GemRepositoryImpl(instance())
}
}
val domainModule: Kodein.Module = Kodein.Module {
bind<Scheduler>(tag = "threadExecutor") with provider {
Schedulers.io()
}
bind<FindGemUseCase>() with provider {
FindGemUseCase(
instance(),
instance(tag = "threadExecutor"),
instance(tag = "postThread")
)
}
}
val presentationModule: Kodein.Module = Kodein.Module {
bind() from setBinding<ViewModelEntry>()
bind<ViewModelEntry>().inSet() with provider {
GemViewModel::class.java to GemViewModel(instance())
}
bind<Map<Class<out ViewModel>, ViewModel>>() with provider {
instance<ViewModelEntries>().toMap()
}
bind<ViewModelProvider.Factory>() with singleton {
ViewModelFactory(instance())
}
}
val dependencyGraph: Kodein.Module = Kodein.Module {
import(cacheModule)
import(dataModule)
import(domainModule)
import(presentationModule)
}
And then, in my application class…
class MyApp : Application(), KodeinAware {
override val kodein : Kodein = Kodein {
import(dependencyGraph)
bind<Context>() with provider {
this@MyApp
}
bind<Scheduler>(tag = "postThread") with singleton {
AndroidSchedulers.mainThread()
}
constant(tag = "resourceId") with R.array.cache
}
}
And MainActivity class…
class MainActivity : AppCompatActivity(), KodeinAware {
override val kodein: Kodein by closestKodein()
private val viewModelFactory: ViewModelProvider.Factory by instance()
private val viewModel: GemViewModel by lazy {
ViewModelProviders.of(this, viewModelFactory).get(GemViewModel::class.java)
}
...
}
And here comes the killer, when I run the app on an Android api 19 or lower, I got this error on logcat:
04-18 19:43:21.952 3706-3706/me.la.leo.kodeindemo E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.StackOverflowError
at org.kodein.di.TypesKt.getJavaType(types.kt)
at org.kodein.di.TypesKt.getJavaType(types.kt:140)
at org.kodein.di.TypesKt.getJavaType(types.kt:140)
at org.kodein.di.TypesKt.getJavaType(types.kt:140)
at org.kodein.di.TypesKt.getJavaType(types.kt:140)
at org.kodein.di.TypesKt.getJavaType(types.kt:140)
at org.kodein.di.TypesKt.getJavaType(types.kt:140)
at org.kodein.di.TypesKt.getJavaType(types.kt:140)
at org.kodein.di.TypesKt.getJavaType(types.kt:140)
at org.kodein.di.TypesKt.getJavaType(types.kt:140)
at org.kodein.di.TypesKt.getJavaType(types.kt:140)
at org.kodein.di.TypesKt.getJavaType(types.kt:140)
at org.kodein.di.TypesKt.getJavaType(types.kt:140)
at org.kodein.di.TypesKt.getJavaType(types.kt:140)
at org.kodein.di.TypesKt.getJavaType(types.kt:140)
at org.kodein.di.TypesKt.getJavaType(types.kt:140)
at org.kodein.di.TypesKt.getJavaType(types.kt:140)
at org.kodein.di.TypesKt.getJavaType(types.kt:140)
at org.kodein.di.TypesKt.getJavaType(types.kt:140)
...
The weird thing is that this works well on api 21 and higher Also, when I replace kodein 5.0.0 with 4.1.0, everything works on api 19 and lower
You can find the sample code here
The master branch is kodein 4.1.0 implementation The kodein5 is kodein 5.0.0 implementation
Issue Analytics
- State:
- Created 5 years ago
- Comments:7 (2 by maintainers)
Top GitHub Comments
Fixed in 5.0.1 😃
Android SDK 19 and lower have many quirks in their reflexivity implementation. I confess I haven’t tested on SDK 19.
I’ll correct this for Kodein 5.0.1. I’ll keep you posted 😉