简体   繁体   中英

Koin DI crashes with release signed apk

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM