[英]Kotlin Room Database - How to perform Sum Query on column?
我是 Kotlin 和 Android 編程的新手。 我需要一些關於我的代碼的幫助。 我正在嘗試對我的房間數據庫中的列執行 SUM 查詢,到目前為止它給我帶來了麻煩。 我試圖讓值返回為 Double 並且應用程序每次都會崩潰。 列,expenseAmount 是一個 Double 類型的列。
這是我到目前為止所擁有的:
道:
@Dao
interface ExpenseDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun addExpense(expense: Expense)
@Query("SELECT * FROM ExpenseListTable ORDER BY id ASC")
fun readAllExpenseData(): LiveData<List<Expense>>
@Delete
suspend fun deleteExpense(expense: Expense)
@Query("SELECT SUM(expenseAmount) FROM ExpenseListTable")
fun getTotalExpense():Double
}
存儲庫:
class ExpenseRepository(private val expenseDao: ExpenseDao) {
val readAllData:LiveData<List<Expense>> = expenseDao.readAllExpenseData()
suspend fun addExpense(expense: Expense){
expenseDao.addExpense(expense)
}
suspend fun deleteExpense(expense: Expense){
expenseDao.deleteExpense(expense)
}
fun getTotal(): Double {
return expenseDao.getTotalExpense()
}
}
查看 Model:
class ExpenseViewModel(application: Application): AndroidViewModel(application) {
val readAllExpenseData: LiveData<List<Expense>>
private val repository: ExpenseRepository
init {
val expenseDao = ExpenseDatabase.getDatabase(application).ExpenseDao()
repository = ExpenseRepository(expenseDao)
readAllExpenseData = repository.readAllData
}
fun addExpense(expense: Expense){
viewModelScope.launch(Dispatchers.IO) {
repository.addExpense(expense)
}
}
fun deleteExpense(expense: Expense){
viewModelScope.launch(Dispatchers.IO) {
repository.deleteExpense(expense)}
}
fun getTotalExpense():Double{
return repository.getTotal()
}
}
活動.kt
val sum = mExpenseViewModel.getTotalExpense()
這是錯誤:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.momoney101/com.android.momoney101.ExpenseList}: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
at androidx.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:267)
at androidx.room.RoomDatabase.query(RoomDatabase.java:323)
at androidx.room.util.DBUtil.query(DBUtil.java:83)
at com.android.momoney101.data.ExpenseDao_Impl.getTotalExpense(ExpenseDao_Impl.java:157)
at com.android.momoney101.repository.ExpenseRepository.getTotal(ExpenseRepository.kt:27)
at com.android.momoney101.viewmodel.ExpenseViewModel.getTotalExpense(ExpenseViewModel.kt:61)
at com.android.momoney101.ExpenseList.onCreate(ExpenseList.kt:69)
at android.app.Activity.performCreate(Activity.java:8000)
at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
我對下一步該做什么有點困惑。 感謝您的時間。
在您的 ViewModel 中,您應該在viewModelScope
中調用getTotalExpense()
堆棧跟蹤表明您正在主線程中進行查詢,您必須在后台線程中進行查詢,否則您必須使用以下代碼。
private fun buildDatabase(context: Context) = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
DbConstants.APP_DB_NAME
).allowMainThreadQueries().fallbackToDestructiveMigration().build()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.