我正在重写一个涉及通过REST从服务器检索数据的应用程序,将其保存到每个Android设备上的数据库中,然后将该数据显示给用户。 从服务器检索的数据具有“自”参数,因此它不会返回所有数据,而仅返回自上次检索以来已更改的数据。
我可以从服务器上正常地进行检索,但是我不确定将数据保存到数据库然后再显示给用户的最佳方法。 我正在使用Kotlin,翻新,Room和LiveData。
下面的代码是我实际上在做的简化版本,但可以理解这一点。
MyData.kt(模型)
@Entity(tableName = "MyTable")
data class MyData(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
var id Int? = null,
@SerializedName("message")
@ColumnInfo(name = "message")
var message: String? = null
) {
companion object {
fun fromContentValues(values: ContentValues): MyData {
val data = MyData()
// Do this for id and message
if (values.containsKey("id") {
data.id = values.getAsInteger("id")
}
}
}
}
DataViewModel.kt
class DataViewModel(application: Application) : AndroidViewModel(application) {
private val repository = DataRepository()
fun data(since: Long) =
liveData(Dispatchers.IO) {
val data = repository.getDataFromServer(since)
emit(data)
}
fun saveData(data: List) =
liveData(Dispatchers.Default) {
val result = repository.saveDataToDatabase(data)
emit(result)
}
fun data() =
liveData(Dispatchers.IO) {
val data = repository.getDataFromDatabase()
emit(data)
}
}
DataRepository.kt
class DataRepository(application: Application) {
// I won't add how the Retrofit client is created, it's standard
private var client = "MyUrlToGetDataFrom"
private var myDao: MyDao
init {
val myDatabase = MyDatabase.getDatabase(application)
myDao = myDatabase!!.myDao()
}
suspend fun getDataFromServer(since: Long): List {
try {
return client.getData(since)
} catch (e: Exception) {
}
}
fun getDataFromDatabase(): List = myDao.getAll()
suspend fun insertData(data: List) =
myDao.insertData(data)
}
MyDao.kt
@Dao
interface PostsDao {
@Query("SELECT * FROM " + Post.TABLE_NAME + " ORDER BY " + Post.COLUMN_ID + " desc")
suspend fun getAllData(): List
@Insert
suspend fun insertData(data: List)
}
ListActivity.kt
private lateinit var mDataViewModel: DataViewModel
override fun onCreate(savedInstanceBundle: Bundle?) {
super.onCreate(savedInstanceBundle)
mDataViewModel = ViewModelProvider(this, DataViewModelFactory(contentResolver)).get(DataViewModel::class.java)
getData()
}
private fun getData() {
mDataViewModel.data(getSince()).observe(this, Observer {
saveData(it)
})
}
private fun saveData(data: List) {
mDataViewModel.saveData(data)
mDataViewModel.data().observe(this, Observer {
setupRecyclerView(it)
})
}
我被困在ListActivity.kt以及可能使用协程的ViewModel和Repository类中。 getData()可以毫无问题地从服务器检索数据,但是要将其保存到数据库中,然后从数据库中获取保存的数据并将其显示给用户,我不确定这种方法。 如前所述,我正在使用Room,但是Room不允许您访问主线程上的数据库。
记住,我必须先保存在数据库中,然后再从数据库中检索,所以我不希望调用mDataViewModel.data().observe直到将其保存到数据库中。
什么是正确的方法呢? 我尝试在mDataViewModel.saveData()上执行CoroutineScope,然后在.invokeOnCompletion上执行mDataViewModel.data().observe ,但它不会保存到数据库中。 我猜想我的协程做得不正确,但是不确定到底在哪里。
最终还将需要从数据库中删除和更新记录。