【问题标题】:Could not create instance for [type:Factory,primary_type:'yodgorbek.komilov.musobaqayangiliklari.viewmodel.MainViewModel'?无法为 [type:Factory,primary_type:'yodgorbek.komilov.musobaqayangiliklari.viewmodel.MainViewModel' 创建实例?
【发布时间】:2020-07-23 12:39:02
【问题描述】:

我正在开发新闻应用程序,我已经使用 viewmodel 实现了 Koin 依赖注入,但我遇到了以下异常

Process: yodgorbek.komilov.musobaqayangiliklari, PID: 8027
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:502)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 
Caused by: org.koin.core.error.InstanceCreationException: Could not create instance for [type:Factory,primary_type:'yodgorbek.komilov.musobaqayangiliklari.viewmodel.MainViewModel']
at org.koin.core.instance.DefinitionInstance.create(DefinitionInstance.kt:61)
at org.koin.core.instance.FactoryDefinitionInstance.get(FactoryDefinitionInstance.kt:37)
at org.koin.core.definition.BeanDefinition.resolveInstance(BeanDefinition.kt:70)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:165)
at org.koin.core.scope.Scope.get(Scope.kt:128)
at org.koin.androidx.viewmodel.ViewModelResolutionKt$createViewModelProvider$1.create(ViewModelResolution.kt:66)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at org.koin.androidx.viewmodel.ViewModelResolutionKt.getInstance(ViewModelResolution.kt:43)
at org.koin.androidx.viewmodel.ViewModelResolutionKt.getViewModel(ViewModelResolution.kt:23)
at org.koin.androidx.viewmodel.ext.android.LifecycleOwnerExtKt.getViewModel(LifecycleOwnerExt.kt:85)
at yodgorbek.komilov.musobaqayangiliklari.ui.TopHeadlinesFragment$$special$$inlined$viewModel$1.invoke(LifecycleOwnerExt.kt:95)
at yodgorbek.komilov.musobaqayangiliklari.ui.TopHeadlinesFragment$$special$$inlined$viewModel$1.invoke(Unknown Source:0)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at yodgorbek.komilov.musobaqayangiliklari.ui.TopHeadlinesFragment.getViewModel(Unknown Source:7)
at yodgorbek.komilov.musobaqayangiliklari.ui.TopHeadlinesFragment.initViewModel(TopHeadlinesFragment.kt:49)
at yodgorbek.komilov.musobaqayangiliklari.ui.TopHeadlinesFragment.onViewCreated(TopHeadlinesFragment.kt:45)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:892)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2663)
at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2613)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:246)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1425)
at android.app.Activity.performStart(Activity.java:7825)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3294)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)

panpam, [10.04.20 20:03]
2020-04-10 19:35:23.798 8027-8027/yodgorbek.komilov.musobaqayangiliklari E/AndroidRuntime: at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
... 3 more
Caused by: org.koin.core.error.InstanceCreationException: Could not create instance for [type:Factory,name:'appModules', primary_type:'yodgorbek.komilov.musobaqayangiliklari.repository.NewsRepository']
at org.koin.core.instance.DefinitionInstance.create(DefinitionInstance.kt:61)
at org.koin.core.instance.FactoryDefinitionInstance.get(FactoryDefinitionInstance.kt:37)
at org.koin.core.definition.BeanDefinition.resolveInstance(BeanDefinition.kt:70)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:165)
at org.koin.core.scope.Scope.get(Scope.kt:128)
at yodgorbek.komilov.musobaqayangiliklari.di.application.module.AppModulesKt$appModules$1$2.invoke(appModules.kt:28)
at yodgorbek.komilov.musobaqayangiliklari.di.application.module.AppModulesKt$appModules$1$2.invoke(Unknown Source:4)
at org.koin.core.instance.DefinitionInstance.create(DefinitionInstance.kt:54)
... 43 more
Caused by: org.json.JSONException: No value for id
at org.json.JSONObject.get(JSONObject.java:399)
at yodgorbek.komilov.musobaqayangiliklari.database.SourceTypeConverters.toSource(SourceTypeConverters.kt:19)
at yodgorbek.komilov.musobaqayangiliklari.database.SportNewsDao_Impl.getAllData(SportNewsDao_Impl.java:242)
at yodgorbek.komilov.musobaqayangiliklari.repository.NewsRepository.<init>(NewsRepository.kt:14)
at yodgorbek.komilov.musobaqayangiliklari.di.application.module.AppModulesKt$appModules$1$1.invoke(appModules.kt:15)
at yodgorbek.komilov.musobaqayangiliklari.di.application.module.AppModulesKt$appModules$1$1.invoke(Unknown Source:4)
at org.koin.core.instance.DefinitionInstance.create(DefinitionInstance.kt:54)

在 appModules.kt 下

val appModules = module() {
    factory(named("appModules")) {
        NewsRepository(sportNewsApi = get(), sportNewsDao = get())
    }
    // factory<NewsRepository> { (NewsRepositoryImpl(sportsNewsApi = get())) }
    // Specific viewModel pattern to tell Koin how to build MainViewModel
    viewModel { MainViewModel(newsRepository = get(named("appModules"))) }



}

在 MainViewModel.kt 下

@Suppress("UNCHECKED_CAST")
class MainViewModel(val newsRepository: NewsRepository) : ViewModel(), CoroutineScope {
    // Coroutine's background job
    val job = Job()
    // Define default thread for Coroutine as Main and add job
    override val coroutineContext: CoroutineContext = Dispatchers.Main + job

    private val _showLoading = MutableLiveData<Boolean>()
    private val _sportList = MutableLiveData<Results>()

    val showLoading: LiveData<Boolean>
        get() = _showLoading

    val sportList: LiveData<Results>
        get() = _sportList


    fun loadNews() {
// Show progressBar during the operation on the MAIN (default) thread
        _showLoading.value = true
// launch the Coroutine
        launch {
            // Switching from MAIN to IO thread for API operation
// Update our data list with the new one from API
            val result = withContext(Dispatchers.IO) {
                newsRepository.refresh()
            }
            _sportList.value = result
            _showLoading.value = false
        }
    }

    override fun onCleared() {
        job.cancel()
    }

}

在 NewsRepository.kt 下方

class NewsRepository(private val sportNewsApi: SportNewsInterface, private val sportNewsDao: SportNewsDao) {



        val data = sportNewsDao.getAllData()

    suspend fun refresh() = withContext(Dispatchers.IO) {
        val articles = sportNewsApi.getNewsAsync().body()?.articles
        if (articles != null) {
            sportNewsDao.addAll(articles)
            Results.Success(articles)
        } else {
            Results.Failure("MyError")
        }
    }
}

在 app.gradle 下

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "yodgorbek.komilov.musobaqayangiliklari"
        minSdkVersion 15
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }


    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }

    dataBinding {
        enabled = true
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.koin:koin-androidx-scope:2.0.1"
// Koin AndroidX ViewModel features
    implementation "org.koin:koin-androidx-viewmodel:2.0.1"
// Koin AndroidX Experimental features
    implementation "org.koin:koin-androidx-ext:2.0.1"

    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.core:core-ktx:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'com.squareup.retrofit2:retrofit:2.6.2'
    implementation 'com.squareup.retrofit2:converter-gson:2.6.2'
    implementation 'com.google.code.gson:gson:2.8.6'

    def lifecycle_version = "2.1.0"
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0-rc03'

    implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'
    // ViewModel and LiveData
    implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
    // alternatively - just ViewModel
    implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
    // For Kotlin use lifecycle-viewmodel-ktx
    // alternatively - just LiveData
    implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
    // alternatively - Lifecycles only (no ViewModel or LiveData). Some UI
    //     AndroidX libraries use this lightweight import for Lifecycle
    implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"

    annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
    // For Kotlin use kapt instead of annotationProcessor
    // alternately - if using Java8, use the following instead of lifecycle-compiler
    implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"

    // optional - ReactiveStreams support for LiveData
    implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version"
    // For Kotlin use lifecycle-reactivestreams-ktx
    implementation 'com.google.android.material:material:1.0.0'
    implementation 'androidx.cardview:cardview:1.0.0'
    implementation 'androidx.recyclerview:recyclerview:1.0.0'
    implementation 'com.github.bumptech.glide:glide:4.8.0'
    // optional - Test helpers for LiveData
    testImplementation "androidx.arch.core:core-testing:$lifecycle_version"
    implementation 'com.squareup.picasso:picasso:2.71828'
    implementation 'com.google.android.material:material:1.0.0-alpha3'


    implementation 'androidx.cardview:cardview:1.0.0'

    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'

    implementation 'com.squareup.okhttp3:okhttp:4.2.1'
    implementation "com.squareup.okhttp3:logging-interceptor:4.2.1"

    def room_version = "2.2.5"

    implementation "androidx.room:room-runtime:$room_version"
    implementation "androidx.room:room-ktx:$room_version"
  //  implementation "androidx.room:room-coroutines:$room_version"
    kapt "androidx.room:room-compiler:$room_version"
    // For Kotlin use kapt instead of annotationProcessor

    // optional - Kotlin Extensions and Coroutines support for Room
    implementation "androidx.room:room-ktx:$room_version"

    // Core library
    androidTestImplementation 'androidx.test:core:1.0.0'

    // AndroidJUnitRunner and JUnit Rules
    androidTestImplementation 'androidx.test:runner:1.1.0'
    androidTestImplementation 'androidx.test:rules:1.1.0'

    // Assertions
    androidTestImplementation 'androidx.test.ext:junit:1.0.0'
    androidTestImplementation 'androidx.test.ext:truth:1.0.0'
    androidTestImplementation 'com.google.truth:truth:0.42'

    // Espresso dependencies
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
    androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.1.0'
    androidTestImplementation 'androidx.test.espresso:espresso-intents:3.1.0'
    androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.1.0'
    androidTestImplementation 'androidx.test.espresso:espresso-web:3.1.0'
    androidTestImplementation 'androidx.test.espresso.idling:idling-concurrent:3.1.0'
    androidTestImplementation 'com.agoda.kakao:kakao:2.2.0'
    androidTestImplementation 'com.21buttons:fragment-test-rule:2.0.1'
    debugImplementation 'com.21buttons:fragment-test-rule-extras:2.0.1'
    debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.0-alpha-3'

    androidTestImplementation 'androidx.test.espresso:espresso-idling-resource:3.1.0'
    implementation 'com.github.denzcoskun:ImageSlideshow:0.0.6'



    implementation 'com.github.bumptech.glide:glide:4.10.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0'
}

在我的 SportNewsDao.kt 下方

@Dao
interface SportNewsDao {

        @Query("SELECT * FROM  Article")
        fun getAllData(): List<Article>

        @Insert
        suspend fun addAll(article: List<Article>)


        @Update
        suspend fun updateArticle(article: Article)

        @Delete
        suspend fun deleteArticle(article: Article)

    }

databaseModule.kt 下

val databaseModule = module {
    fun provideDatabase(application: Application): SportNewsDatabase {
        return Room.databaseBuilder(application, SportNewsDatabase::class.java, "sportNews.database")
            .fallbackToDestructiveMigration()
            .allowMainThreadQueries()
            .build()
    }


    fun provideDao(database: SportNewsDatabase): SportNewsDao {
        return database.sportNewsDao()
    }

    single { provideDatabase(androidApplication()) }
    single { provideDao(get()) }


}

在 SportNewsDatabase.kt 下方

Database(entities = [Article::class], version = 1, exportSchema = false)
@TypeConverters(SourceTypeConverters::class)
abstract class SportNewsDatabase : RoomDatabase() {

    abstract fun sportNewsDao(): SportNewsDao

    companion object {
        private var instance: SportNewsDatabase? = null
        fun getInstance( context: Context): SportNewsDatabase? {
            if (instance == null) {
                synchronized(SportNewsDatabase::class.java) {
                    instance = Room.databaseBuilder(context.applicationContext, SportNewsDatabase::class.java, "article_database")
                        .fallbackToDestructiveMigration()
                        .build()
                }
            }
            return instance
        }
    }


}

repositoryModule.kt

val repositoryModule = module {
    fun provideUserRepository(sportsNewsApi: SportNewsInterface, sportNewsDao: SportNewsDao): NewsRepository {
        return NewsRepository(sportsNewsApi, sportNewsDao)
    }

    single { provideUserRepository(get(), get()) }
}

在我的 koin 初始化下面

class SportNewsApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        // Adding Koin modules to our application
        startKoin {
            androidContext(this@SportNewsApplication)
            modules(listOf(netModule, appModules, bbcModules, espnModules, footballItaliaModules, databaseModule, repositoryModule, viewModelModule))
        }

    }
}

我不明白是什么导致我尝试过的崩溃发生

  1. 缓存重启无效
  2. 清洁重建项目
  3. Checked Dao class by debugging id 即将到来。
  4. 我在我的应用程序中创建了另一个 viewModelModule 并初始化 MainViewModel,但它没有解决我的问题。
  5. 我也试过关注koin github issus link
  6. 我已经完成了下面所有建议的答案,但应用程序仍然在上面给出异常
  7. 按照建议从 appModules.kt 中删除了工厂名称,但仍然出现异常。
  8. 我已经尝试了我在 stackoverflow 中提到的所有可能的解决方案,但都没有解决问题。

我想知道我在哪里犯了错误我必须做什么以避免崩溃 任何帮助和建议将不胜感激。

【问题讨论】:

  • 您指的是这个问题吗? @sashabeliy
  • 是的 Jeel Vaknkhade 即使我在 koin github repo 上创建了问题也没有人回复
  • 好的,我一有空就会回复你。
  • @JeelVankhede 好的,我会等你的回复
  • 你能把factory(named("appModules")) { NewsRepository(sportNewsApi = get(), sportNewsDao = get()) } 从appModule 中删除,看看它是否有效。我怀疑您已经将NewRepository 作为RepositoryModules 中的单身注入。所以你也不需要创建它的工厂对象。也可以直接写MainViewModel(newsRepository = get())

标签: android kotlin mvvm android-viewmodel koin


【解决方案1】:

您尝试获取 sportNewsApisportNewsDao ,但它们不在模块中。将它们添加到模块中

【讨论】:

  • 如何将它们添加到模块中
【解决方案2】:

Val anymodule = 模块 { 单 { sportNewsApiImpl() }

}

其中sportsNewsApiImpl是实现sportNewsApi接口的类

【讨论】:

  • single { get.sportNewsDao() }
  • Singhhal 你能解释一下你的编码示例吗?
  • koin需要sportNewApi对象和sportNewDao对象来提供。
  • 你能清楚地重新编辑你的答案吗?它会有所帮助
  • 您需要在koin中提供sportNewApi对象和sportNewDao对象。 SportNewApi 是一个接口,你有一些实现类让我们说 SportNewApiImpl ...你像 Single{SportNewApiImpl () } 一样提供它。现在你必须提供你可以使用房间数据库实例获得的 sportNewsDao 实例,所以你提供了如上所示的房间数据库....在你提供了这样一个 {get.sportNewsDao()} 的 sportNewsDao 之后
【解决方案3】:
I have solved problem following way I  have an extra NewsRepository class definition. If I have already created one class definition, then I do not need to create it again

val appModules = module {


    // Specific viewModel pattern to tell Koin how to build MainViewModel

    // factory<NewsRepository> { (NewsRepositoryImpl(sportsNewsApi = get())) }
    // Specific viewModel pattern to tell Koin how to build MainViewModel
    viewModel { MainViewModel(newsRepository = get()) }
}


class NewsRepository(
    private val sportNewsApi: SportNewsInterface,
    private val sportNewsDao: SportNewsDao
) {


    val data = sportNewsDao.getAllData()

    suspend fun refresh() = withContext(Dispatchers.IO) {
        val articles = sportNewsApi.getNewsAsync().body()?.articles
        if (articles != null) {
            sportNewsDao.addAll(articles)
            Results.Success(articles)
        } else {
            Results.Failure("MyError")
        }
    }
}

【讨论】:

  • 我也遇到了同样的问题,你是怎么解决的???
【解决方案4】:

您可能忘记创建 APIService 接口的实例,例如

single { get().create(ForgotPasswordService::class.java) }

网络模块中的这个

【讨论】:

    猜你喜欢
    • 2020-03-30
    • 2021-04-12
    • 1970-01-01
    • 2020-01-16
    • 2019-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多