gpt4 book ai didi

java - Realm 返回陈旧数据

转载 作者:搜寻专家 更新时间:2023-10-30 23:36:19 26 4
gpt4 key购买 nike

我没有太多编写 Android 应用程序的经验。为了好玩,我正在编写一个应用程序,它将我的通话记录上传到我的服务器。整个应用程序作为服务运行。该服务(在手机启动时启动)是注册 ContentObserver 的服务,然后调用我的自定义 CallLog 类。我使用 ContentObserver 来监听内容更改事件。不幸的是,当我例如拨一个号码。

因此,我有一个在成功上传(我使用 Retrofit)后调用的函数,名为 markAsUploaded()。此函数创建一个名为 CallLogUploadedRealmObject(这与我的常规 CallLog 模型不同)。此 CallLogUploaded 仅具有一个标识符,即调用的 dateTime,它应该足够唯一。然后,当我遍历所有调用日志的列表时,我根据 isDataUploaded() 函数检查每个调用日志,该函数执行 Realm 查询并检查是否已经有调用记录存储在数据库( Realm )中的日期时间。理论上,它应该有效。

但是,我注意到它并不总是有效。似乎我的数据经常过时。当我执行 realm.isAutoRefresh() 时,它返回 false(尽管我发誓它返回 true 一次)。在我的 isDataUploaded 函数中,即使当我在 Realm 上执行 findAll() 时,我也看不到我的所有数据 - 但数据确实命中了 markDataAsUploaded 函数。

这是我的代码 - 它在 Kotlin 中,但应该很容易理解:

    val callLogCall = service.sendCalLLogs(childId, dataToUpload)
callLogCall.enqueue(object : Callback<Void> {
override fun onResponse(call: Call<Void>, response: Response<Void>) {
if (response.isSuccessful) {
Log.i(AppConstants.LOG_TAG, "Call log data uploaded successfully!")
this@CallLogData.markDataAsUploaded(dataToUpload)
} else {
Log.w(AppConstants.LOG_TAG, "Call log data upload failed")
}
}

override fun onFailure(call: Call<Void>, t: Throwable) {
Log.w(AppConstants.LOG_TAG, "Call log data upload error (onFailure) called")
}
})


// This function simply stores a Realm model for all the data that has been uploaded to the server
private fun markDataAsUploaded(dataToUpload: List<CallLog>) {
realm = Realm.getDefaultInstance()
for (data in dataToUpload) {
realm.beginTransaction()
val callLogUploaded = realm.createObject(CallLogUploaded::class.java)
callLogUploaded.callDate = data.callDate

realm.commitTransaction()
}
}

// This function checks to see if the data is already uploaded.
private fun isDataUploaded(callLog: CallLog) : Boolean {
return realm
.where(CallLogUploaded::class.java)
.equalTo("callDate", callLog.callDate)
.count() > 0L
}

// Gets the call logs - not the entire function
for (call in callLogs) {
val callLog = CallLog()
callLog.id = call.id
callLog.callDate = Utilities.getTimestampAsSeconds(call.callDate)

if (this.isDataUploaded(callLog)) {
continue
}

callLog.name = call.name
callLog.number = call.number
}

我是 Realm 的新手,也是 Android 开发的新手,所以如果您能给我任何帮助,我将不胜感激。谢谢!

最佳答案

那是因为

// This function simply stores a Realm model for all the data that has been uploaded to the server
private fun markDataAsUploaded(dataToUpload: List<CallLog>) {
realm = Realm.getDefaultInstance()
for (data in dataToUpload) {
realm.beginTransaction()
val callLogUploaded = realm.createObject(CallLogUploaded::class.java)
callLogUploaded.callDate = data.callDate

realm.commitTransaction()
}
}

这个方法有quite a few errors that I had written about a long time ago

  • Realm 实例已打开,但从未关闭

  • 每个元素都有一个新事务,而不是在一个事务中插入所有元素

如果您不关闭 Realm 实例(每个实例都需要它自己的 close() 调用),那么您的 Realm 实例将永远不会更新,除非您实际开始一个事务并在事务中执行操作.

您有三种解决方案:

1.) 在事务内的后台线程上执行您的逻辑,如果无事可做,则取消事务 - 在事务中进行的查询永远不会过时

2.) 确保正确关闭 Realm 实例(尽管这在任何非自动更新线程上绝对是必需的)

3.) 一个 hacky 解决方案是调用 RealmRefresh.refreshRealm() after getDefaultInstance() according to my answer on Stack Overflow which relies on package-private API, but it works to solve this issue


通常您需要在线程开始时打开 Realm 实例,并在线程结束时关闭它。

所以,它基本上是 try(Realm realm = Realm.getDefaultInstance() { ... } for onHandleIntent()


enqueue(new Callback() { @Override public void onSuccess(..) {...} 在 UI 线程上运行。要在当前线程上运行它,您应该使用 call.execute().


代替

for (data in dataToUpload) {
realm.beginTransaction()
val callLogUploaded = realm.createObject(CallLogUploaded::class.java)
callLogUploaded.callDate = data.callDate

realm.commitTransaction()
}

realm.beginTransaction()
for (data in dataToUpload) {
val callLogUploaded = realm.createObject(CallLogUploaded::class.java)
callLogUploaded.callDate = data.callDate
}
realm.commitTransaction()

要了解版本保留,您可以阅读 https://medium.com/@Zhuinden/understanding-realm-version-retention-and-synchronization-9a513c2445bb .

关于java - Realm 返回陈旧数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41924862/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com