Не удалось создать экземпляр для [type: Factory, primary_type: 'yodgorbek.komilov.musobaqayangiliklari.viewmodel.MainViewModel'? - PullRequest
0 голосов
/ 10 апреля 2020

Я занимаюсь разработкой приложения новостей. Я реализовал внедрение зависимостей Koin с помощью viewmodel, но получаю следующее исключение

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)

    }

ниже базы данныхModule. 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))
        }

    }
}

Я сделал не понимаю, что заставляет cra sh происходить то, что я пробовал

  1. Неправильный перезапуск кэша
  2. Очистить проект перестроения
  3. Проверен класс Dao с помощью идентификатора отладки.
  4. Я создал еще один viewModelModule и инициализировал MainViewModel в моем приложении, но это не решило мою проблему.
  5. Я пробовал также koin github issus link .
  6. Я сделал все, что предлагает ответ ниже бу Приложение все еще дает исключение выше
  7. удалил фабрику с именем appModules.kt, как это было предложено, но это все еще появляется исключение.
  8. Я испробовал все возможные решения, которые я упомянул в stackoverflow, это не решило проблему .

Я хочу знать, где я делаю ошибку, что я должен делать, чтобы избежать краха, любая помощь и предложения будут оценены.

Ответы [ 3 ]

1 голос
/ 12 апреля 2020

Val anymodule = module {single {sportNewsApiImpl ()}

}

, где sportsNewsApiImpl - это класс, который реализует интерфейс sportNewsApi

0 голосов
/ 21 апреля 2020
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")
        }
    }
}
0 голосов
/ 10 апреля 2020

Вы пытались получить sportNewsApi и sportNewsDao, но их нет в модуле. Добавьте их в модуль

...