为什么在使用 ViewModel 实例时无法将数据存储在 Room 中?

问题描述 投票:0回答:0

我使用 hashmap 在我的 Fragment UserFragment 中创建了一个简单的数据,我希望每次单击 Store 按钮单击侦听器时将特定的键值存储在 Room 数据库中,为此我创建了 Room 和 Repository 所需的特定类和 ViewModel 类但是当我尝试从 viewModel 访问所需的数据时出现错误。下面是我的代码

姓名地址.kt

@Entity(tableName = "info")
data class NameAddress(
    @PrimaryKey
    val id:Int,
    @ColumnInfo(name = "name1")
    val name1:String,
    @ColumnInfo(name = "address")
    val address:String
    )

道接口 名称地址Dao.kt

@Dao
interface NameAddressDao {

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insertNameAddress(nameAddress: NameAddress)

}

Room 数据库构建器类 AppDatabase.kt

@Database(entities = [NameAddress::class], version = 1)
abstract class AppDatabase:RoomDatabase() {


    abstract fun nameAddressDao():NameAddressDao

    companion object{
        @Volatile
        private var INSTANCE:AppDatabase?=null

        fun getDatabase(context: Context):AppDatabase{

            var tempInstance = INSTANCE
            if(tempInstance!=null){
                return tempInstance

            }
            synchronized(this){
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    AppDatabase::class.java,
                    "my_database"
                ).build()
                INSTANCE = instance
                return instance
            }
        }
    }
}

名称地址存储库.kt

class NameAddressRepository(private val nameAddressDao: NameAddressDao) {

    suspend fun insertNameAddress(nameAddress: NameAddress){
       nameAddressDao.insertNameAddress(nameAddress)
    }

}

下面是我想在片段中使用的 ViewModel 类。 NameAddressViewModel.kt

class NameAddressViewModel(private val nameAddressRepository: NameAddressRepository):ViewModel() {

    fun insertNameAddress(id:Int,name:String, address:String){
        val nameAddress = NameAddress(id,name,address)

        viewModelScope.launch {
            nameAddressRepository.insertNameAddress(nameAddress)
        }
    }


}

所以最终我按照以下方式在我的片段 UserFragment.kt 中实现了视图模型的实例。

import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.ViewModelProvider
import com.example.sharedviewmodeldemo.data.AppDatabase
import com.example.sharedviewmodeldemo.data.NameAddress
import com.example.sharedviewmodeldemo.data.NameAddressViewModel
import com.example.sharedviewmodeldemo.databinding.FragmentUserBinding
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch


class UserFragment : Fragment() {

    private lateinit var binding: FragmentUserBinding
    lateinit var db:AppDatabase

    lateinit var nameAddressViewModel: NameAddressViewModel

    private var hashMap=HashMap<String, String>()
    private val totalPairs=4
    private var currentPairIndex=0
    private val tag:String = "Room"

    private lateinit var currentPair:Map.Entry<String,String>

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        binding = FragmentUserBinding.inflate(layoutInflater,container,false)

        hashMap["Robert"] = "NYC"
        hashMap["John"] = "Phoenix"
        hashMap["Alice"] = "London"
        hashMap["Kara"] = "Tennessee"

        //retrieve current pair
        currentPair = hashMap.entries.elementAt(currentPairIndex)
        binding.txtName.text = currentPair.key
        binding.txtAddress.text = hashMap.get(currentPair.key)


         nameAddressViewModel = ViewModelProvider(this)[NameAddressViewModel::class.java]


        binding.btnFlip.setOnClickListener {
            // increment currentPairIndex and get the next pair
            currentPairIndex++
            if (currentPairIndex >= hashMap.size) {
                // if we have reached the end of the hashmap, start again from the beginning
                currentPairIndex = 0
            }
            currentPair = hashMap.entries.elementAt(currentPairIndex)

            // update the UI with the new pair
            binding.txtName.text = currentPair.key
            binding.txtAddress.text=hashMap.get(currentPair.key)

        }

        binding.btnStore.setOnClickListener {

                  val currentName = currentPair.key
                  val currentAddress = hashMap.get(currentPair.key)

            val nameAddress = currentAddress?.let { it1 -> NameAddress(0,currentName, it1) }

            GlobalScope.launch {
                   db = nameAddressViewModel.insertNameAddress(0,currentName,currentAddress!!) //this line is giving me error
                     Log.i(tag,"$nameAddress")
            }

        }

        return binding.root
    }


}
android mvvm hashmap android-room android-viewmodel
© www.soinside.com 2019 - 2024. All rights reserved.