使用 Factory 将 ViewModel 注入 Fragment 时找不到 RoomDatabase 的实现
cannot find implementation for RoomDatabase while injecting ViewModel into Fragment with Factory
我正在努力处理视图模型注入。我一直在学习教程并稍微更改了代码以适应我的需要,但是应用程序崩溃了。
我有 App
class 持有我的 DaggerComponent 及其模块。在它的 onCreate 里面我有:
component = DaggerAppComponent.builder().daoModule(DaoModule(this)).build()
我的 AppModule:
@Singleton
@Component(modules = [DaoModule::class, ViewModelModule::class])
interface AppComponent {
val factory: ViewModelFactory
}
视图模型模块:
@Module
abstract class ViewModelModule {
@Binds
@Singleton
abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
@Binds
@Singleton
@IntoMap
@ViewModelKey(TaskViewModel::class)
abstract fun splashViewModel(viewModel: TaskViewModel): ViewModel
}
我的工厂:
@Singleton
class ViewModelFactory @Inject constructor(
private val viewModels: MutableMap<Class<out ViewModel>,
@JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T =
viewModels[modelClass]?.get() as T
}
我这里使用了ViewModelKey、ViewModelModule和Factory,以及Fragment扩展函数来进行Fragment viewmodel注入。我在网上找到它并在以前的项目中成功使用了它。这是我的 util 函数:
@MainThread
inline fun <reified VM : ViewModel> Fragment.daggerViewModels(
noinline ownerProducer: () -> ViewModelStoreOwner = { this }
) = createViewModelLazy(
VM::class,
{ ownerProducer().viewModelStore },
{ App.component.factory }
)
还有我的 DaoModule。
@Module
class DaoModule(private val app: Application) {
@Provides
@Singleton
fun getDB(): TaskDatabase = TaskDatabase.getAppDatabase(context())
@Provides
@Singleton
fun context(): Context = app.applicationContext
@Provides
fun gettaskDao(taskDatabase: TaskDatabase) : TaskDao = taskDatabase.TaskDao()
}
我的实体:
@Entity(tableName = "userinfo")
data class Task(
@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: Int = 0,
@ColumnInfo(name = "name") val name: String,
@ColumnInfo(name = "email") val email: String,
@ColumnInfo(name = "phone") val phone: String?
)
我的任务数据库如下:
@Database(entities = [Task::class], version = 1)
abstract class TaskDatabase : RoomDatabase() {
abstract fun TaskDao(): TaskDao
companion object {
private var INSTANCE: TaskDatabase? = null
fun getAppDatabase(context: Context): TaskDatabase {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(
context.applicationContext, TaskDatabase::class.java, "AppDBB"
)
.allowMainThreadQueries()
.build()
}
return INSTANCE!!
}
}
}
My Dao 界面。
@Dao
interface TaskDao {
@Query("SELECT * FROM userinfo")
fun getAllTaskInfo(): List<Task>?
@Insert
fun insertTask(user: Task?)
@Delete
fun deleteTask(user: Task?)
@Update
fun updateTask(user: Task?)
}
现在我有一个逻辑来在我的 Fragment 中初始化我的 TaskViewModel 并将观察者附加到我的任务列表。但是应用程序崩溃了。
在我的片段中我有:
val viewModel: TaskViewModel by daggerViewModels { requireActivity() }
还有:
DaggerFragmentComponent
.builder()
.appComponent((requireActivity().application as App).getAppComponent())
.build()
.inject(this)
viewModel.allTaskList.observe(viewLifecycleOwner) {
// textView.text = it.toString()
}
而我的TaskViewModel class如下:
class TaskViewModel @Inject constructor(var taskDao: TaskDao) : ViewModel() {
private var _allTaskList = MutableLiveData<List<Task>>()
val allTaskList = _allTaskList as LiveData<List<Task>>
init {
getAllRecords()
}
private fun getAllRecords() = _allTaskList.postValue(taskDao.getAllTaskInfo())
fun insertTask(task: Task) {
taskDao.insertTask(task)
getAllRecords()
}
}
现在我知道这是很多代码,但是有人可以帮我解决这个问题吗?匕首看到它的图形,因为我可以构建项目,因此提供了所有依赖项。我在这里做错了什么?我的 logcat:
我自己找到了解决方案。这个不见了。
implementation 'androidx.room:room-runtime:2.5.0-alpha01'
我正在努力处理视图模型注入。我一直在学习教程并稍微更改了代码以适应我的需要,但是应用程序崩溃了。
我有 App
class 持有我的 DaggerComponent 及其模块。在它的 onCreate 里面我有:
component = DaggerAppComponent.builder().daoModule(DaoModule(this)).build()
我的 AppModule:
@Singleton
@Component(modules = [DaoModule::class, ViewModelModule::class])
interface AppComponent {
val factory: ViewModelFactory
}
视图模型模块:
@Module
abstract class ViewModelModule {
@Binds
@Singleton
abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
@Binds
@Singleton
@IntoMap
@ViewModelKey(TaskViewModel::class)
abstract fun splashViewModel(viewModel: TaskViewModel): ViewModel
}
我的工厂:
@Singleton
class ViewModelFactory @Inject constructor(
private val viewModels: MutableMap<Class<out ViewModel>,
@JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T =
viewModels[modelClass]?.get() as T
}
我这里使用了ViewModelKey、ViewModelModule和Factory,以及Fragment扩展函数来进行Fragment viewmodel注入。我在网上找到它并在以前的项目中成功使用了它。这是我的 util 函数:
@MainThread
inline fun <reified VM : ViewModel> Fragment.daggerViewModels(
noinline ownerProducer: () -> ViewModelStoreOwner = { this }
) = createViewModelLazy(
VM::class,
{ ownerProducer().viewModelStore },
{ App.component.factory }
)
还有我的 DaoModule。
@Module
class DaoModule(private val app: Application) {
@Provides
@Singleton
fun getDB(): TaskDatabase = TaskDatabase.getAppDatabase(context())
@Provides
@Singleton
fun context(): Context = app.applicationContext
@Provides
fun gettaskDao(taskDatabase: TaskDatabase) : TaskDao = taskDatabase.TaskDao()
}
我的实体:
@Entity(tableName = "userinfo")
data class Task(
@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: Int = 0,
@ColumnInfo(name = "name") val name: String,
@ColumnInfo(name = "email") val email: String,
@ColumnInfo(name = "phone") val phone: String?
)
我的任务数据库如下:
@Database(entities = [Task::class], version = 1)
abstract class TaskDatabase : RoomDatabase() {
abstract fun TaskDao(): TaskDao
companion object {
private var INSTANCE: TaskDatabase? = null
fun getAppDatabase(context: Context): TaskDatabase {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(
context.applicationContext, TaskDatabase::class.java, "AppDBB"
)
.allowMainThreadQueries()
.build()
}
return INSTANCE!!
}
}
}
My Dao 界面。
@Dao
interface TaskDao {
@Query("SELECT * FROM userinfo")
fun getAllTaskInfo(): List<Task>?
@Insert
fun insertTask(user: Task?)
@Delete
fun deleteTask(user: Task?)
@Update
fun updateTask(user: Task?)
}
现在我有一个逻辑来在我的 Fragment 中初始化我的 TaskViewModel 并将观察者附加到我的任务列表。但是应用程序崩溃了。
在我的片段中我有:
val viewModel: TaskViewModel by daggerViewModels { requireActivity() }
还有:
DaggerFragmentComponent
.builder()
.appComponent((requireActivity().application as App).getAppComponent())
.build()
.inject(this)
viewModel.allTaskList.observe(viewLifecycleOwner) {
// textView.text = it.toString()
}
而我的TaskViewModel class如下:
class TaskViewModel @Inject constructor(var taskDao: TaskDao) : ViewModel() {
private var _allTaskList = MutableLiveData<List<Task>>()
val allTaskList = _allTaskList as LiveData<List<Task>>
init {
getAllRecords()
}
private fun getAllRecords() = _allTaskList.postValue(taskDao.getAllTaskInfo())
fun insertTask(task: Task) {
taskDao.insertTask(task)
getAllRecords()
}
}
现在我知道这是很多代码,但是有人可以帮我解决这个问题吗?匕首看到它的图形,因为我可以构建项目,因此提供了所有依赖项。我在这里做错了什么?我的 logcat:
我自己找到了解决方案。这个不见了。
implementation 'androidx.room:room-runtime:2.5.0-alpha01'