android-studio - 没有 livedata 的 Android Studio Room 数据
问题描述
我得到了以下 Room 数据库,并希望在文本视图中输出随机用户的名称。不幸的是,运行代码会产生输出:文本视图中的kotlin.unit。我的文件如下所示:
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var mNameViewModel: NameViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mNameViewModel = ViewModelProvider(this).get(NameViewModel::class.java)
val btn = findViewById<Button>(R.id.btn_addName)
val tv = findViewById<TextView>(R.id.tv_showName)
btn.setOnClickListener {
val text = findViewById<EditText>(R.id.et_enterName)?.text.toString()
val name = Name(0, text)
// Add Data to Database
mNameViewModel.addName(name)
Toast.makeText(applicationContext, "Successfully added $text.", Toast.LENGTH_LONG).show()
val randomName = mNameViewModel.getRandomName()
// Without .toString() I get an error, with it it displays kotlin.unit
tv.text = randomName.toString()
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv_showName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.133" />
<EditText
android:id="@+id/et_enterName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:hint="Name"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.244" />
<Button
android:id="@+id/btn_addName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.379" />
</androidx.constraintlayout.widget.ConstraintLayout>
名称.kt
@Entity(tableName = "name_data")
data class Name (
@PrimaryKey(autoGenerate = true) val id: Int,
@ColumnInfo(name = "name") val name: String
)
NameDao.kt
@Dao
interface NameDao {
@Insert
fun addName(name: Name)
@Query("SELECT name FROM name_data ORDER BY RANDOM() LIMIT 1")
fun getRandomName(): String
}
名称数据库.kt
@Database(entities = [Name::class], version = 1, exportSchema = false)
abstract class NameDatabase: RoomDatabase() {
abstract fun nameDao(): NameDao
companion object{
@Volatile
private var INSTANCE: NameDatabase? = null
fun getDatabase(context: Context): NameDatabase{
val tempInstance = INSTANCE
if(tempInstance != null){
return tempInstance
}
synchronized(this){
val instance = databaseBuilder(
context.applicationContext,
NameDatabase::class.java,
"name_data"
).build()
INSTANCE = instance
return instance
}
}
}
}
NameRepository.kt
class NameRepository(private val nameDao: NameDao) {
fun getRandomName() { nameDao.getRandomName() }
fun addName(name: Name) { nameDao.addName(name) }
}
NameViewModel.kt
class NameViewModel(application: Application): AndroidViewModel(application) {
private val repository: NameRepository
init {
val nameDao = NameDatabase.getDatabase(application).nameDao()
repository = NameRepository(nameDao)
}
fun addName(name: Name) {
viewModelScope.launch(Dispatchers.IO){
repository.addName(name)
}
}
fun getRandomName() {
viewModelScope.launch(Dispatchers.IO){
repository.getRandomName()
}
}
}
这是按下按钮时textview的输出方式。
数据库被填充了。
感谢任何帮助以显示数据。谢谢!
解决方案
问题是,在getRandomNumber
viewmodel 内部的方法中,您没有返回任何内容,这就是您得到kotlin.unit
. 相反,您应该确保返回一个值
一个可能的解决方案如下。
- 在您的 dao 中创建一个方法,该方法接受一个数字并返回该行(这实际上是随机名称)
- 从您的 repo 调用该方法,您可以使用随机数
Random.getNextInt
不确定如何获得随机数 - 从您的视图模型调用该方法
- 从您的按钮 onClick 调用 viewModel 方法
确保suspend
在适用的地方使用以获得结果。对于我上面展示的情况,将在视图级别启动协程并进行其余调用(vm、repo、dao)suspend
推荐阅读
- python - 正则表达式:提取一个由 "" 包围的 27 长字符子字符串
- xml - XML 和 XSLT - 单独的节点包括逗号
- apache-kafka - 卡夫卡经纪人重启后卡夫卡主题不平衡
- javascript - 如何在对象 vanilla JavaScript 中将一个变量分配给另一个变量
- javascript - React 中的 Axios.delete:`Error:DELETE chrome-extension://...`
- sql-server - 如果您想在根存储过程中调用其他存储过程,仅在根存储过程中使用 SET NOCOUNT ON 是否正确
- javascript - 获取滑块以更新 HTML 画布
- c# - 自定义winforms框架的最佳方法?
- xamarin.forms - 如何将主详细信息页面设为根页面?
- angular - Chart Js的onClick函数内的访问组件变量