我正在开发新闻应用程序,我已经用viewmodel实现了Koin depenendcy注入,但我得到了以下异常
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
}
}
}
存储库Module.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))
}
}
}
我不明白是什么导致了崩溃我试过
- 使缓存重新启动无效
- 清理重建项目
- 通过调试id检查的Dao类即将出现
- 我在应用程序中创建了另一个viewModelModule并初始化了MainViewModel,但它并没有解决我的问题
- 我也尝试过关注koin github issus链接
- 我已经完成了下面的所有建议答案,但上面的应用程序仍有例外
- 按照建议从appModules.kt中删除了名为的工厂,但它仍然出现异常
- 我已经尝试了所有可能的解决方案,我在stackoverflow中提到的并没有解决问题
我想知道我在哪里犯了错误我必须做些什么才能避免崩溃任何帮助和建议都将不胜感激。
Val-anymodule=module{单个{sportNewsApiImpl((}
}
其中sportsNewsApiImpl是实现sportNewsApi接口的类
您试图获取sportNewsApi
和sportNewsDao
,但它们不在模块中。将它们添加到模块
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")
}
}
}
您可能忘记创建像这样的APIService接口实例
single{get((.create(ForgotPasswordService::class.java(}
这个在网络模块中