【问题标题】:Cannot access elements with a specific attribute from my dao (Android Room)无法从我的 dao (Android Room) 访问具有特定属性的元素
【发布时间】:2020-08-16 15:14:38
【问题描述】:

我正在制作一个包含多个用户的 toDoList 应用程序。我有两个实体。一个是用户,另一个是任务

@Entity(tableName = "tasks")
data class Task(
@PrimaryKey(autoGenerate = true)
val id : Int,
val taskUserId : Int,
val taskName : String,
val taskDescription : String,
var taskPriority : Int)


@Entity(tableName = "users")
data class User(
@PrimaryKey
val userId : Int,
val userName : String,
val password : String)

如您所见,这两个实体需要有一个共同点,那就是用户 ID,因此我可以根据用户 ID 查询任务。这就是我的 dao 的样子:

@Dao
interface UserDao {

@Query("SELECT * FROM users")
fun getAllUsers() : LiveData<List<User>>

@Query("SELECT * FROM tasks WHERE taskUserId LIKE :userId ORDER BY taskPriority DESC")
fun getAllUsersTasks(userId : Int) : LiveData<List<Task>>

@Insert
suspend fun saveUser(user : User)

@Insert
suspend fun saveTask(task : Task)
}

以下是其他模型元素:

class TaskRepository(private val userDao: UserDao) {

var userId : Int = 0
val allTasks = userDao.getAllUsersTasks(userId)
val allUsers : LiveData<List<User>> = userDao.getAllUsers()

suspend fun saveUser(user : User){
    userDao.saveUser(user)
}

suspend fun saveTask(task : Task){
    userDao.saveTask(task)
    }
}

还有 ViewModel:

class MainViewModel(application: Application) : AndroidViewModel(application) {

private val taskRepository : TaskRepository

val allTasks : LiveData<List<Task>>
val allUsers : LiveData<List<User>>
private var userId  : Int = 0


init {
    val taskDao = UserTasksDatabase.getDatabase(application)!!.userDao()
    taskRepository = TaskRepository(taskDao)
    allTasks = taskRepository.allTasks
    allUsers = taskRepository.allUsers
    taskRepository.userId = this.userId
}


fun saveUser(user: User) = viewModelScope.launch(Dispatchers.IO){
    taskRepository.saveUser(user)
}

fun saveTask(task: Task) = viewModelScope.launch(Dispatchers.IO){
    taskRepository.saveTask(task)
}

fun setUserId(id : Int){
    this.userId = id
}

fun getUserId() : Int{
    return this.userId
    }

}

当用户按下登录或注册按钮时,我在 viewModel 中设置用户 ID

 logInButton.setOnClickListener {
        val userName: String = userNameEditText.text.toString()
        val password: String = passwordEditText.text.toString()
        val id: Int = IdMaker.generateId(userName)
        val user = User(id, userName, password)

        if(listOfAllUsers.contains(user)){
            sharedViewModel.setUserId(id)
            Toast.makeText(requireContext(), "Welcome $userName", Toast.LENGTH_LONG).show()
            fragmentManager!!.beginTransaction().apply {
                replace(R.id.fl_activity_main, MainFragment())
                commit()
            }
        }else{
            Toast.makeText(requireContext(), "The user already exists", Toast.LENGTH_LONG).show()
        }
    }

但是当我尝试访问主片段中的用户并将它们设置在我的 recyclerview 上时,我什么也没得到。而且我真的看不出我错过了什么。

sharedViewModel.allTasks.observe(this, Observer {tasks ->
        tasks.let { adapter.setTasks(it) }
    })

如果问题有点简单,我很抱歉,但我希望我能深入了解我错过了什么。

附注:recyclerview 已正确设置并经过测试。

【问题讨论】:

    标签: kotlin android-recyclerview android-room dao entities


    【解决方案1】:

    我认为您没有正确设置TaskRepository.userId

    class MainViewModel(application: Application) : AndroidViewModel(application) {
        private val taskRepository : TaskRepository
        private var userId  : Int = 0
    
        init {
            ...
            // init is called only once at the start of this viewModel's instance creation
            // Here, you set your repository's userId to 0
            taskRepository.userId = this.userId
        }
    }
    

    在创建MainViewModel 的实例时,将其TaskRepository 实例的userId 设置为0,在您的以下代码中不再更改。单击登录按钮后,您会调用:

    sharedViewModel.setUserId(id)
    

    但该函数仅更改 viewModel 的 userId 属性,而不是 TaskRepository 实例的 userId 属性。所以试试:

    class MainViewModel(application: Application) : AndroidViewModel(application) {
        private lateinit var taskRepository : TaskRepository
        val allTasks = taskRepository.allTasks
        val allUsers = taskRepository.allUsers
    
    
        // remove init {}
        
        fun setUserId(id : Int){
            // set up the repository only after userId is known
            val taskDao = UserTasksDatabase.getDatabase(application)!!.userDao()
            taskRepository = TaskRepository(taskDao, id)
        }
    }
    

    改变你的TaskRepository 类:

    class TaskRepository(private val userDao: UserDao, private val userId: Int) {
        val allTasks: LiveData<List<Task>> 
            get() = userDao.getAllUsersTasks(userId)
        val allUsers: LiveData<List<User>>
            get() = userDao.getAllUsers()
    
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 2022-06-15
      • 2019-01-22
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-20
      相关资源
      最近更新 更多