首页 > 解决方案 > Kotlin Room Database - 如何对列执行求和查询?

问题描述

我是 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()
    }
}

查看型号:

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) 

我对下一步该做什么有点困惑。感谢您的时间。

标签: androidkotlinandroid-room

解决方案


在您的 ViewModel 中,您应该getTotalExpense()viewModelScope


推荐阅读