I have an application that uses Koin DI framework. I have set all the modules for Retrofit, Database, Repository etc and works fine in the debug mode. Lately i uploaded it on Play Store but i see that it crashes when i try to launch the app. The problem is that it cannot create an Instance for my Repository class which of course has its dependencies. Here is the error that i get on my Logcat
2020-09-09 17:23:37.690 19662-19662/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mypackage.myapp, PID: 19662
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mypackage.myapp/com.mypackage.ui.activities.accounts.accountlist.AccountsListActivity}: org.koin.core.error.InstanceCreationException: Could not create instance for [Single:'com.mypackage.repositories.server.ServerRepository']
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3632)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3784)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2270)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8125)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
Caused by: org.koin.core.error.InstanceCreationException: Could not create instance for [Single:'com.mypackage.repositories.server.ServerRepository']
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:59)
at org.koin.core.instance.SingleInstanceFactory.create(SingleInstanceFactory.kt:40)
at org.koin.core.instance.SingleInstanceFactory.get(SingleInstanceFactory.kt:48)
at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:87)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:214)
at org.koin.core.scope.Scope.get(Scope.kt:181)
at com.mypackage.ui.activities.accounts.accountlist.AccountsViewModel$$special$$inlined$inject$1.invoke(KoinComponent.kt:67)
at kotlin.UnsafeLazyImpl.getValue(Lazy.kt:81)
at com.mypackage.ui.activities.accounts.accountlist.AccountsViewModel.getServerRepository(Unknown Source:2)
at com.mypackage.ui.activities.accounts.accountlist.AccountsViewModel.getServerAccounts(AccountsViewModel.kt:37)
at com.mypackage.ui.activities.accounts.accountlist.AccountsListActivity.onCreate(AccountsListActivity.kt:97)
at android.app.Activity.performCreate(Activity.java:7957)
at android.app.Activity.performCreate(Activity.java:7946)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3607)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3784)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2270)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8125)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
Caused by: org.koin.core.error.InstanceCreationException: Could not create instance for [Single:'com.mypackage.managers.api.ApiManager']
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:59)
at org.koin.core.instance.SingleInstanceFactory.create(SingleInstanceFactory.kt:40)
at org.koin.core.instance.SingleInstanceFactory.get(SingleInstanceFactory.kt:48)
at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:87)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:214)
at org.koin.core.scope.Scope.get(Scope.kt:181)
at com.mypackage.di.ModulesKt$repositoryModule$1$1.invoke(Modules.kt:208)
at com.mypackage.di.ModulesKt$repositoryModule$1$1.invoke(Unknown Source:4)
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:50)
at org.koin.core.instance.SingleInstanceFactory.create(SingleInstanceFactory.kt:40)
at org.koin.core.instance.SingleInstanceFactory.get(SingleInstanceFactory.kt:48)
at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:87)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:214)
at org.koin.core.scope.Scope.get(Scope.kt:181)
at com.mypackage.ui.activities.accounts.accountlist.AccountsViewModel$$special$$inlined$inject$1.invoke(KoinComponent.kt:67)
at kotlin.UnsafeLazyImpl.getValue(Lazy.kt:81)
at com.mypackage.ui.activities.accounts.accountlist.AccountsViewModel.getServerRepository(Unknown Source:2)
at com.mypackage.ui.activities.accounts.accountlist.AccountsViewModel.getServerAccounts(AccountsViewModel.kt:37)
at com.mypackage.ui.activities.accounts.accountlist.AccountsListActivity.onCreate(AccountsListActivity.kt:97)
at android.app.Activity.performCreate(Activity.java:7957)
at android.app.Activity.performCreate(Activity.java:7946)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3607)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3784)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2270)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8125)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
Caused by: org.koin.core.error.InstanceCreationException: Could not create instance for [Single:'retrofit2.Retrofit$Builder']
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:59)
at org.koin.core.instance.SingleInstanceFactory.create(SingleInstanceFactory.kt:40)
at org.koin.core.instance.SingleInstanceFactory.get(SingleInstanceFactory.kt:48)
at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:87)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:214)
2020-09-09 17:23:37.691 19662-19662/? E/AndroidRuntime: at org.koin.core.scope.Scope.get(Scope.kt:181)
at com.mypackage.di.ModulesKt$managersModule$1$3.invoke(Modules.kt:204)
at com.mypackage.di.ModulesKt$managersModule$1$3.invoke(Unknown Source:4)
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:50)
... 33 more
Caused by: org.koin.core.error.InstanceCreationException: Could not create instance for [Single:'okhttp3.OkHttpClient']
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:59)
at org.koin.core.instance.SingleInstanceFactory.create(SingleInstanceFactory.kt:40)
at org.koin.core.instance.SingleInstanceFactory.get(SingleInstanceFactory.kt:48)
at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:87)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:214)
at org.koin.core.scope.Scope.get(Scope.kt:181)
at com.mypackage.di.ModulesKt$networkModule$1$7.invoke(Modules.kt:204)
at com.mypackage.di.ModulesKt$networkModule$1$7.invoke(Unknown Source:4)
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:50)
... 41 more
Caused by: java.lang.IllegalStateException: Single instance created couldn't return value
at org.koin.core.instance.SingleInstanceFactory.get(SingleInstanceFactory.kt:50)
at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:87)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:214)
at org.koin.core.scope.Scope.get(Scope.kt:181)
at com.mypackage.di.ModulesKt$networkModule$1$6.invoke(Modules.kt:200)
at com.mypackage.di.ModulesKt$networkModule$1$6.invoke(Unknown Source:4)
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:50)
... 49 more
My build.gradle is below
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: "androidx.navigation.safeargs"
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
android {
compileSdkVersion 30
defaultConfig {
applicationId "com.mypackage"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
lintOptions {
checkReleaseBuilds false
}
resConfigs "en"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
kotlinOptions {
jvmTarget = '1.8'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
flavorDimensions "version"
productFlavors {
myapp {
dimension "version"
applicationIdSuffix ".myapp"
versionCode 2
versionName "1.2"
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
implementation 'com.google.android.material:material:1.3.0-alpha02'
implementation 'androidx.recyclerview:recyclerview:1.2.0-alpha05'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'io.github.luizgrp.sectionedrecyclerviewadapter:sectionedrecyclerviewadapter:1.2.0'
implementation 'androidx.exifinterface:exifinterface:1.2.0'
// Firebase && Crashlytics
implementation 'com.google.firebase:firebase-core:17.5.0'
implementation 'com.google.firebase:firebase-messaging:20.2.4'
implementation 'com.google.firebase:firebase-crashlytics:17.2.1'
implementation 'com.google.firebase:firebase-analytics:17.5.0'
// Lifecycle (ViewModel & LiveData)
def lifecycle_version = "2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// Gson to Kotlin Object
implementation 'com.google.code.gson:gson:2.8.6'
// Coroutines for Kotlin
def coroutines_version = "1.3.5"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
// Room Database
def room_version = "2.2.5"
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-ktx:$room_version"
kapt "androidx.room:room-compiler:$room_version"
// Koin DI
def koin_version = "2.1.6"
implementation "org.koin:koin-core:$koin_version"
implementation "org.koin:koin-android:$koin_version"
// Navigation Components
def nav_version = "2.3.0"
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
// Butterknife
def butterknifeVersion = '10.2.0'
implementation "com.jakewharton:butterknife:10.2.3"
kapt "com.jakewharton:butterknife-compiler:10.2.3"
// Preferences
implementation "androidx.preference:preference:1.1.1"
// Work Manager (Kotlin + coroutines)
implementation "androidx.work:work-runtime-ktx:2.4.0"
// Paging
implementation 'androidx.paging:paging-runtime-ktx:2.1.2'
// Circle Image view
implementation 'de.hdodenhof:circleimageview:3.1.0'
// Gallery picker
implementation 'com.kroegerama:bottomsheet-imagepicker:1.1.2'
// Sliding up Panel
implementation 'com.sothree.slidinguppanel:library:3.4.0'
// Material Search bar
implementation 'com.github.mancj:MaterialSearchBar:0.8.2'
// Material About page
implementation 'com.github.jrvansuita:MaterialAbout:0.2.3'
// Material Spinner
implementation 'com.github.chivorns.androidx:smartmaterialspinner:1.2.1'
// Pin Lock View
implementation 'com.chaos.view:pinview:1.4.3'
// Image editor
implementation 'com.github.iamutkarshtiwari:Ananas:1.2.4'
// Volley SyncRequests
implementation 'com.android.volley:volley:1.1.1'
// Retrofit Requests
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'
implementation 'com.squareup.retrofit2:converter-simplexml:2.9.0'
// Retrofit logging interceptor
implementation 'com.squareup.okhttp3:logging-interceptor:4.8.1'
// Glide for ImageLoading
implementation 'com.github.bumptech.glide:glide:4.11.0'
kapt 'com.github.bumptech.glide:compiler:4.11.0'
// Video Compress
implementation "com.github.AbedElazizShe:LightCompressor:0.7.0"
// Qr Code scanner
implementation 'me.dm7.barcodescanner:zxing:1.9.13'
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
// Twilio
implementation "com.twilio:video-android:5.6.0"
implementation "com.twilio:audioswitch:0.1.0"
implementation "com.twilio:twilio-android-env:1.0.0"
// OpenCv for Grayscale video
// implementation "com.quickbirdstudios:opencv:3.4.1"
// -----DEBUG MODE--- //
// Database monitor --for Emulator we run "adb forward tcp:8080 tcp:8080"
debugImplementation 'com.amitshekhar.android:debug-db:1.0.6'
// Logback
implementation 'org.slf4j:slf4j-api:1.7.30'
implementation 'com.github.tony19:logback-android:2.0.0'
}
The modules declaration for the Koin is the following
import androidx.room.Room
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import org.koin.android.ext.koin.androidContext
import org.koin.dsl.module
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit
val networkModule = module {
single<Gson> {
val gsonBuilder = GsonBuilder()
return@single gsonBuilder.setLenient().create()
}
single<Interceptor?> {
if (!BuildConfig.DEBUG) return@single null
val httpLoggingInterceptor = HttpLoggingInterceptor()
httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
return@single httpLoggingInterceptor
}
single {
return@single HeaderInterceptor()
}
single {
return@single NetworkResponseAdapterFactory()
}
single {
return@single BaseUrlHolder(BuildConfig.BASE_HOLDER_URL)
}
single<OkHttpClient> {
val loggingInterceptor = get<Interceptor?>()
val httpClientBuilder = OkHttpClient().newBuilder().apply {
connectTimeout(60, TimeUnit.SECONDS)
readTimeout(60, TimeUnit.SECONDS)
writeTimeout(60, TimeUnit.SECONDS)
addInterceptor(get<HeaderInterceptor>())
loggingInterceptor?.let {
addInterceptor(loggingInterceptor)
}
}
return@single httpClientBuilder.build()
}
single<Retrofit.Builder> {
return@single Retrofit.Builder()
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.addConverterFactory(GsonConverterFactory.create(get()))
.client(get<OkHttpClient>())
}
single<MyAppApiService> {
return@single get<Retrofit>().create(MyAppApiService::class.java)
}
}
val databaseModule = module {
single {
return@single BuildConfig.DATABASE_NAME
}
single {
return@single Room
.databaseBuilder(androidContext(), AppDatabase::class.java, get())
.build()
}
single {
get<AppDatabase>().serverDao()
}
single {
get<AppDatabase>().accountsDao()
}
single {
get<AppDatabase>().siteDao()
}
single {
get<AppDatabase>().accountGroupsDao()
}
single {
get<AppDatabase>().siteRolesDao()
}
single {
get<AppDatabase>().formsDao()
}
single {
get<AppDatabase>().messageDao()
}
single {
get<AppDatabase>().messageQueueDao()
}
}
val repositoryModule = module {
single<ServerRepository> {
return@single ServerRepositoryImpl(get(), get(), get())
}
single<AccountsRepository> {
return@single AccountsRepositoryImpl(
get(),
get(),
get(),
get(),
get(),
get(),
get(),
get(),
get(),
androidContext(),
get()
)
}
single<FormsRepository> {
return@single FormsRepositoryImpl(get())
}
single<MessagesRepository> {
return@single MessagesRepositoryImpl(get(), get(), get(), get(), get(), get(), androidContext())
}
single<FriendShipRepository> {
return@single FriendShipRepositoryImpl(get(), get(), get())
}
}
val managersModule = module {
single<SharedPrefsData<Settings>> {
return@single SharedPrefsDataImpl<Settings>(androidContext(), Settings.prefsName)
}
single<SharedPrefsManager> {
return@single SharedPrefsManagerImpl(androidContext(), get())
}
single<ApiManager> {
return@single ApiManagerImpl(get(), get())
}
single<RoomManager> {
return@single RoomManagerImpl(androidContext(), get(), get())
}
}
val lifecycleModule = module {
single {
return@single MyAppLifeCycleObserver()
}
}
Why is this happening since the Koin is set up correclty (because it works in debug mode)???
The problem solved. It seems that the provider for httpLoggingInterceptor that return NULL if it is debug mode could not create the single. So i changed my code to
single<Interceptor> {
val httpLoggingInterceptor = HttpLoggingInterceptor()
httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
return@single httpLoggingInterceptor
}
.....
single {
val httpClientBuilder = OkHttpClient().newBuilder().apply {
connectTimeout(60, TimeUnit.SECONDS)
readTimeout(60, TimeUnit.SECONDS)
writeTimeout(60, TimeUnit.SECONDS)
addInterceptor(get<HeaderInterceptor>())
if (!BuildConfig.DEBUG) addInterceptor(get<Interceptor>())
}
return@single httpClientBuilder.build()
}
Now it works.