无法找到实现(Room)

11 浏览
0 Comments

无法找到实现(Room)

我在Room或者我真不知道问题出在哪里遇到了问题,我需要帮助找出问题出在哪里。我正在使用Hilt DI,在创建数据库的实例时出现了崩溃,以下是我的代码:

【错误信息】

E/AndroidRuntime: FATAL EXCEPTION: main

Process: com.example.todo, PID: 1895

java.lang.RuntimeException: cannot find implementation for com.example.todo.data.ToDoDatabase. ToDoDatabase_Impl does not exist

at androidx.room.Room.getGeneratedImplementation(Room.java:97)

at androidx.room.RoomDatabase$Builder.build(RoomDatabase.java:1358)

at com.example.todo.di.AppModule.provideToDoDatabase(AppModule.kt:27)

at com.example.todo.di.AppModule_ProvideToDoDatabaseFactory.provideToDoDatabase(AppModule_ProvideToDoDatabaseFactory.java:33)

at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC.toDoDatabase(DaggerMainApplication_HiltComponents_SingletonC.java:69)

at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC.access$2000(DaggerMainApplication_HiltComponents_SingletonC.java:48)

at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC$SwitchingProvider.get(DaggerMainApplication_HiltComponents_SingletonC.java:583)

at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)

at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC.toDoDao(DaggerMainApplication_HiltComponents_SingletonC.java:73)

at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC.access$1900(DaggerMainApplication_HiltComponents_SingletonC.java:48)

at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC$SwitchingProvider.get(DaggerMainApplication_HiltComponents_SingletonC.java:580)

at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)

at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC$ViewModelCImpl.toDoRepository(DaggerMainApplication_HiltComponents_SingletonC.java:448)

at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC$ViewModelCImpl.toDoViewModel(DaggerMainApplication_HiltComponents_SingletonC.java:452)

at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC$ViewModelCImpl.access$1700(DaggerMainApplication_HiltComponents_SingletonC.java:429)

at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC$ViewModelCImpl$SwitchingProvider.get(DaggerMainApplication_HiltComponents_SingletonC.java:487)

at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory$1.create(HiltViewModelFactory.java:100)

at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:69)

at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:84)

at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:109)

at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:171)

at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:139)

at androidx.lifecycle.ViewModelLazy.getValue(ViewModelLazy.kt:44)

at androidx.lifecycle.ViewModelLazy.getValue(ViewModelLazy.kt:31)

at com.example.todo.fragments.add.AddFragment.getViewModel(AddFragment.kt:20)

at com.example.todo.fragments.add.AddFragment.insertDataToDo(AddFragment.kt:63)

at com.example.todo.fragments.add.AddFragment.onOptionsItemSelected(AddFragment.kt:45)

at androidx.fragment.app.Fragment.performOptionsItemSelected(Fragment.java:3122)

at androidx.fragment.app.FragmentManager.dispatchOptionsItemSelected(FragmentManager.java:3226)

at androidx.fragment.app.Fragment.performOptionsItemSelected(Fragment.java:3126)

at androidx.fragment.app.FragmentManager.dispatchOptionsItemSelected(FragmentManager.java:3226)

at androidx.fragment.app.FragmentController.dispatchOptionsItemSelected(FragmentController.java:416)

at androidx.fragment.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:358)

at androidx.appcompat.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:264)

at androidx.appcompat.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:109)

at androidx.appcompat.app.AppCompatDelegateImpl.onMenuItemSelected(AppCompatDelegateImpl.java:1179)

at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:834)

at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)

at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:985)

at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:975)

at androidx.appcompat.widget.ActionMenuView.invokeItem(ActionMenuView.java:624)

at androidx.appcompat.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:151)

at android.view.View.performClick(View.java:7441)

at android.view.View.performClickInternal(View.java:7418)

at android.view.View.access$3700(View.java:835)

at android.view.View$PerformClick.run(View.java:28676)

at android.os.Handler.handleCallback(Handler.java:938)

at android.os.Handler.dispatchMessage(Handler.java:99)

at android.os.Looper.loopOnce(Looper.java:201)

at android.os.Looper.loop(Looper.java:288)

at android.app.ActivityThread.main(ActivityThread.java:7842)

at java.lang.reflect.Method.invoke(Native Method)

at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

【build.gradle】

plugins {

id 'com.android.application'

id 'kotlin-android'

id 'kotlin-kapt'

id 'androidx.navigation.safeargs.kotlin'

id 'dagger.hilt.android.plugin'

id 'kotlin-parcelize'

}

android {

compileSdk 31

defaultConfig {

applicationId "com.example.todo"

minSdk 24

targetSdk 31

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'

}

buildFeatures {

dataBinding true

viewBinding true

}

}

dependencies {

implementation 'androidx.legacy:legacy-support-v4:1.0.0'

def nav_version = "2.3.5"

def room_version = "2.3.0"

def lifecycle_version = "2.4.0"

implementation 'androidx.core:core-ktx:1.7.0'

implementation 'androidx.appcompat:appcompat:1.3.1'

implementation 'com.google.android.material:material:1.4.0'

implementation 'androidx.constraintlayout:constraintlayout:2.1.1'

testImplementation 'junit:junit:'

androidTestImplementation 'androidx.test.ext:junit:1.1.3'

androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

//Navigation component

implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"

implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

//Room

implementation "androidx.room:room-runtime:$room_version"

annotationProcessor "androidx.room:room-compiler:$room_version"

// Lifecycle

implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"

implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"

//Kotlin coroutines

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0'

//RecyclerView

implementation 'jp.wasabeef:recyclerview-animators:4.0.2'

//Hilt DI

implementation "com.google.dagger:hilt-android:2.38.1"

kapt "com.google.dagger:hilt-compiler:2.38.1"

}

【ToDoData.kt】

@Entity(tableName = "todo_table")

@Parcelize

data class ToDoData(

@PrimaryKey(autoGenerate = true)

var id: Int,

var title: String,

var description: String,

var priority: Priority

) : Parcelable

【ToDoDatabase.kt】

@Database(entities = [ToDoData::class], version = 1, exportSchema = false)

@TypeConverters(Converter::class)

abstract class ToDoDatabase : RoomDatabase() {

abstract fun toDoDao(): ToDoDao

}

【ToDoViewModel.kt】

@HiltViewModel

class ToDoViewModel @Inject constructor(

private val repository: ToDoRepository

) : ViewModel() {

private val getAllData: LiveData> = repository.getAllData

fun insertData(toDoData: ToDoData) {

viewModelScope.launch(Dispatchers.IO) {

repository.insertData(toDoData)

}

}

}

【AppModule.kt】

@Module

@InstallIn(SingletonComponent::class)

object AppModule {

@Singleton

@Provides

fun provideToDoDatabase(

@ApplicationContext app: Context

) = Room.databaseBuilder(

app,

ToDoDatabase::class.java,

"todo_database"

)

.fallbackToDestructiveMigration()

.build()

@Singleton

@Provides

fun provideTodoDao(db: ToDoDatabase) = db.toDoDao()

}

【AddFragment.kt】

以下是我在AddFragment中调用以插入数据的函数:

private val viewModel: ToDoViewModel by viewModels()

private fun insertDataToDo() {

val title = binding.titleEt.text.toString()

val priority = binding.spinnerPriorities.selectedItem.toString()

val description = binding.descriptionEt.text.toString()

val validation = verifyDataFromUser(title, description)

if (validation) {

val data = ToDoData(

0,

title,

description,

parsePriority(priority)

)

viewModel.insertData(data)

Toast.makeText(requireContext(), "Successfully Added!", Toast.LENGTH_SHORT).show()

findNavController().navigate(R.id.action_addFragment_to_listFragment)

} else

Toast.makeText(requireContext(), "Please fill out all fields", Toast.LENGTH_SHORT)

.show()

}

private fun verifyDataFromUser(title: String, description: String): Boolean {

return if (TextUtils.isEmpty(title) || TextUtils.isEmpty(description)) {

false

} else !(title.isEmpty() || description.isEmpty())

}

private fun parsePriority(priority: String): Priority {

return when (priority) {

"High Priority" -> Priority.HIGH

"Medium Priority" -> Priority.MEDIUM

"Low Priority" -> Priority.LOW

else -> Priority.LOW

}

}

我已经看过这里的一些问题,遇到了相同的问题,但对我没有用,所以我不确定问题出在哪里。

0
0 Comments

原因:出现该问题的原因是在build.gradle文件中的annotationProcessor配置错误。

解决方法:将annotationProcessor改为kapt。

经过更改后的build.gradle文件如下:

// Hilt, Dependency injection

def hilt_version = "2.38.1"

implementation "com.google.dagger:hilt-android:$hilt_version"

kapt "com.google.dagger:hilt-compiler:$hilt_version"

// Room database

def room_version = "2.4.2"

implementation "androidx.room:room-runtime:$room_version"

kapt "androidx.room:room-compiler:$room_version"

以上更改后,问题得到解决。

原文链接:[Stack Overflow](https://stackoverflow.com/questions/69794509)

0