【发布时间】:2020-09-28 06:41:42
【问题描述】:
我无法检索数据。
有什么方法可以访问我们的数据库,我们可以检查到目前为止我们插入的内容。
在这段代码中,我试图插入我在计算器中所做的最新计算以及我的交易数量。使用协程、房间和视图模型。
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.navigation.NavController
import com.kotlin_developer.calculator.database.CalculationDatabaseDao
import com.kotlin_developer.calculator.database.CalculatorHistory
import kotlinx.coroutines.*
import timber.log.Timber
class CalculatorViewModel(
val
database: CalculationDatabaseDao,
application: Application
) : AndroidViewModel(application) {
var operatorEnabled: Boolean = false
var firstResult: Double = 0.0
var operator: Char = ' '
var ifNumeric: Boolean = true
var secondResultLenght = 0
// First step of coroutines is to create job, this can cancel all the coroutines started by this view model
private var viewModelJob = Job()
// Second step is to create the scope where we want to run our code
// Scope determines what thread the coroutines will run on, it also needs to know about the job
private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)
// private val history = database.getAllCalculation()
private var _totalTransaction = MutableLiveData<Int>()
val totalTransaction: LiveData<Int>
get() = _totalTransaction
//Getting currentCalculation
private var _currentCalculation = MutableLiveData<String>()
val currentCalculation: LiveData<String>
get() = _currentCalculation
//Getting current result
private var _currentResult = MutableLiveData<String>()
val currentResult: LiveData<String>
get() = _currentResult
val navControler = MutableLiveData<NavController>()
private val _secondResult = MutableLiveData<Double>()
val secondResult: LiveData<Double>
get() = _secondResult
private var _resultTextValue = MutableLiveData<Double>()
val resultTextValue: LiveData<Double>
get() = _resultTextValue
private var _lastHistory = MutableLiveData<CalculatorHistory>()
val lastHistory: LiveData<CalculatorHistory>
get() = _lastHistory
val totalCalculation = mutableListOf<String>()
init {
Timber.i("Calculator View Model created")
_resultTextValue.value = 0.0
_secondResult.value = 0.0
_totalTransaction.value = 0
}
fun insertData() {
uiScope.launch {
val newHistory = CalculatorHistory(
totalTransaction.value?.toLong()!!,
totalCalculation[totalTransaction.value!! - 1]
)
insert(newHistory)
}
}
private suspend fun insert(newHistory: CalculatorHistory) {
withContext(Dispatchers.IO) {
database.insert(newHistory)
Timber.i("Data Inserted")
}
}
internal fun initializeHistory() {
uiScope.launch {
_lastHistory.value = getHistoryFromDatabase()
}
Timber.i("${lastHistory.value?.transactionNumber} and ${lastHistory.value?.calculation}")
}
private suspend fun getHistoryFromDatabase(): CalculatorHistory? {
return withContext(Dispatchers.IO) {
var lastCalculation = database.get(1)
lastCalculation
}
Timber.i("${lastHistory.value?.transactionNumber} and ${lastHistory.value?.calculation}")
}
fun calculator(operator: Char): Double {
return when (operator) {
'+' -> firstResult.plus(secondResult.value ?: 0.0)
'-' -> firstResult.minus(secondResult.value ?: 0.0)
'*' -> firstResult.times(secondResult.value ?: 1.0)
'/' -> firstResult.div(secondResult.value ?: 1.0)
else -> firstResult.rem(secondResult.value ?: 1.0)
}
}
fun createCalculation() {
ifNumeric = false
operatorEnabled = false
_resultTextValue.value = calculator(operator)
//This we can use in future to create a list of calculation
totalCalculation.add(
totalTransaction.value!!,
"${currentCalculation.value}=${_resultTextValue.value}"
)
_currentResult.value = totalCalculation[totalTransaction.value!!]
insertData()
firstResult = _resultTextValue.value ?: 0.0
_totalTransaction.value = _totalTransaction.value?.plus(1)
_secondResult.value = 0.0
secondResultLenght = 0
}
fun seprateNumber(number: Double) {
if (operatorEnabled) {
if (ifNumeric) {
_secondResult.value = number + (secondResult.value?.times(10.0))!!
} else {
_secondResult.value = number
}
} else {
firstResult = number + (firstResult * 10)
}
}
fun clearText() {
_resultTextValue.value = 0.0
_currentResult.value = ""
firstResult = 0.0
_secondResult.value = 0.0
secondResultLenght = 0
operator = ' '
operatorEnabled = false
ifNumeric = false
_currentCalculation.value = ""
}
fun ifSeprateNumber(number: Double) {
seprateNumber(number)
if (operatorEnabled) {
secondCalculationText()
} else {
_currentCalculation.value = firstResult.toString()
}
ifNumeric = true
}
fun secondCalculationText() {
_currentCalculation.value = _currentCalculation.value
?.removeRange(
_currentCalculation.value!!.length -
secondResultLenght, _currentCalculation.value!!.length
)
_currentCalculation.value =
"${_currentCalculation.value}${secondResult.value.toString()}"
secondResultLenght = secondResult.value.toString().length
ifNumeric = true
}
fun addTextToField() {
ifNumeric = false
operatorEnabled = true
_currentCalculation.value = "${_currentCalculation.value}${operator}"
}
override fun onCleared() {
super.onCleared()
//This cancels all the coroutines when the view model is getting closed
viewModelJob.cancel()
Timber.i("Calculator ViewModel destroyed")
}
}
【问题讨论】:
-
不要创建自己的范围和工作,而是使用 android 提供的
viewModelScope。并在DAO接口中使用suspend关键字,而不是手动调度到Dispatchers.IO,从而清理代码然后编辑问题并提问。
标签: android kotlin android-room kotlin-coroutines