同时,我从本地源下载数据并检查服务器上的更新。但是由于某些原因,图纸数据不会更新。我使用Firestore。
片段:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
checkUpdate()
getData()
}
private fun checkUpdate() {
viewModel.checkUpdate().observe(viewLifecycleOwner, Observer { result ->
when(result) {
is Response.Loading -> { loading() }
is Response.Success -> {
viewModel.updateData()
}
is Response.Error -> { error(result.exception) }
}
})
}
private fun getData() {
viewModel.getData().observe(viewLifecycleOwner, Observer { result ->
when(result) {
is Response.Loading -> { loading() }
is Response.Success -> { success(result.data) }
is Response.Error -> { error(result.exception) }
}
})
}
ViewModel
private var data: LiveData<Response<List<Rule>>>
init {
data = loadData()
}
fun getData() = data
fun updateData() { data = loadData() }
private fun loadData() =
liveData(viewModelScope.coroutineContext + Dispatchers.IO) {
emit(Response.Loading)
val result = repository.getData()
if (result is Response.Success || result is Response.Error) emit(result)
}
fun checkUpdate() =
liveData(viewModelScope.coroutineContext + Dispatchers.IO) {
val lastUpdateTimestamp = Timestamp(
preferences.getLong("PREF_RULE_LAST_UPDATE", 0),
0
)
emit(Response.Loading)
when(val result = repository.checkUpdate(lastUpdateTimestamp)) {
is Response.Success -> {
if (result.data > lastUpdateTimestamp) {
try {
val editor = preferences.edit()
editor.putLong("PREF_RULE_LAST_UPDATE", result.data.seconds)
editor.apply()
emit(Response.Success(true))
} catch (exception: Exception) {
emit(Response.Error(exception))
}
} else {
emit(Response.Success(false))
}
}
is Response.Error -> { emit(result) }
}
}
存储库
suspend fun getData(): Response<List<Rule>> =
suspendCoroutine { continuation ->
firebaseFirestore
.collection(COLLECTION_NAME)
.whereEqualTo("published", true)
.orderBy("number", Query.Direction.ASCENDING)
.get(Source.CACHE)
.addOnSuccessListener { query ->
try {
val data = arrayListOf<Rule>()
query.documents.forEach {document ->
document.toObject(RuleDomain::class.java)?.let {
it.id = document.id
data.add(it.toRule())
}
}
continuation.resume(Response.Success(data))
} catch (exception: Exception) {
Log.e(TAG, exception.localizedMessage!!)
continuation.resume(Response.Error(exception))
}
}
.addOnFailureListener { exception ->
Log.e(TAG, exception.localizedMessage!!)
continuation.resume(Response.Error(exception))
}
}
suspend fun checkUpdate(lastUpdateTimestamp: Timestamp): Response<Timestamp> =
suspendCoroutine { continuation ->
firebaseFirestore
.collection(COLLECTION_NAME)
.whereGreaterThan("update_timestamp", lastUpdateTimestamp)
.orderBy("update_timestamp", Query.Direction.ASCENDING)
.get(Source.SERVER)
.addOnSuccessListener { query ->
try {
val data = query.documents.first()["update_timestamp"] as Timestamp
continuation.resume(Response.Success(data))
} catch (exception: Exception) {
Log.e(TAG, exception.localizedMessage!!)
continuation.resume(Response.Error(exception))
}
}
.addOnFailureListener { exception ->
Log.e(TAG, exception.localizedMessage!!)
continuation.resume(Response.Error(exception))
}
}
我要替换的是“ data”变量实际上正在更新,因为当旋转屏幕时会出现数据。据我从文档中了解到,viewModel.getData().observe(viewLifecycleOwner, Observer { ... })
应该在该片段处于活动状态时进行签名,并应提交所有更改。
答案 0 :(得分:1)
我决定完全放弃部分代码,并将其重写一下。
片段
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
getData()
}
private fun getData() {
viewModel.data.observe(viewLifecycleOwner, Observer { result ->
when(result) {
is Response.Loading -> { loading() }
is Response.Success -> { success(result.data) }
is Response.Error -> { error(result.exception) }
}
})
}
ViewModel
private var _data: LiveData<Response<List<Rule>>>
val data: LiveData<Response<List<Rule>>>
get() = _data
init {
_data = loadData()
}
private fun loadData(): LiveData<Response<List<Rule>>> =
liveData(viewModelScope.coroutineContext + Dispatchers.IO) {
emit(Response.Loading)
val lastUpdateTimestamp = Timestamp(preferences.getLong("PREF_RULE_LAST_UPDATE", 0), 0)
val response = repository.getData(lastUpdateTimestamp)
if (response is Response.Success) {
val result = response.data
if (result.containsKey("LAST_UPDATE_TIMESTAMP"))
if (result["LAST_UPDATE_TIMESTAMP"] as Timestamp > lastUpdateTimestamp)
preferences.put("PREF_RULE_LAST_UPDATE", (result["LAST_UPDATE_TIMESTAMP"] as Timestamp).seconds)
if (result.containsKey("DATA"))
emit(Response.Success(result["DATA"] as List<Rule>))
}
if (response is Response.Error)
emit(response)
}
存储库
suspend fun getData(timestamp: Timestamp): Response<HashMap<String, Any?>> =
suspendCoroutine { continuation ->
firebaseFirestore
.collection(COLLECTION_NAME)
.whereGreaterThan("update_timestamp", timestamp)
.orderBy("update_timestamp", Query.Direction.DESCENDING)
.get(Source.SERVER)
.addOnCompleteListener { queryServer ->
val hashMap = HashMap<String, Any?>()
if (!queryServer.result?.isEmpty!!)
hashMap["LAST_UPDATE_TIMESTAMP"] = queryServer.result!!.first().get("update_timestamp") as Timestamp
firebaseFirestore
.collection(COLLECTION_NAME)
.whereEqualTo("published", true)
.orderBy("number", Query.Direction.ASCENDING)
.get(Source.CACHE)
.addOnSuccessListener { queryCache ->
try {
val data = arrayListOf<Rule>()
queryCache.documents.forEach {document ->
document.toObject(RuleDomain::class.java)?.let {
it.id = document.id
data.add(it.toRule())
}
}
hashMap["DATA"] = data
continuation.resume(Response.Success(hashMap))
} catch (exception: Exception) {
Log.e(TAG, exception.localizedMessage!!)
continuation.resume(Response.Error(exception))
}
}
.addOnFailureListener { exception ->
Log.e(TAG, exception.localizedMessage!!)
continuation.resume(Response.Error(exception))
}
}
}