SharedPreferences 是一种在服务和 UI 之间共享设置的安全方式吗?

Is SharedPreferences a safe way of sharing settings between a service and the UI?

SharedPreferences 是一种在服务和 UI 之间共享设置的安全方式吗?

我在服务中调用 commit(),当我在 UI 300 毫秒后读取首选项时,数据不存在。这是在 API 27.

我已经使用 Messenger 在服务和 UI 之间进行通信。

这就是我在服务端存储数据的方式:

  local e = context:getSharedPreferences("characters", context.MODE_PRIVATE):edit()
  e:putString("list", table.concat(names, "|"))
  log("saved these names in characters: %s", tstring(names))
  e:commit()
  local stuff = context:getSharedPreferences("characters", context.MODE_PRIVATE)

在 UI 中检索它:

  charlist_settings = activity:getSharedPreferences("characters", activity.MODE_PRIVATE)
  log("refreshlist hit")
  if charlist_settings:contains("list") and charlist_settings:getString("list", "") ~= "" then
    [...]
  else
    log("no list in char_settings :(")
    log("all: %s", charlist_settings:getAll():toString())
  end

服务日志,通知时间戳:

12-22 18:56:30.246 4142-4142/org.vadisystems.irehelper:Service I/IRE Helper: modified is: added
12-22 18:56:30.253 4142-4142/org.vadisystems.irehelper:Service I/IRE Helper: saved these names in characters: {"Vadimuses_Achaea"}

UI 日志,这是在收到来自服务的消息后:

12-22 18:56:30.700 4120-4120/org.vadisystems.irehelper I/IRE Helper: refreshlist hit
12-22 18:56:30.701 4120-4120/org.vadisystems.irehelper I/IRE Helper: no list in char_settings :(
12-22 18:56:30.702 4120-4120/org.vadisystems.irehelper I/IRE Helper: all: {}

使用本地广播接收器,当动作完成时,广播。在监听端,您有一个 class 负责持久保存到 SharedPreferences,并且 UI 可以有一个单独的监听器并自行更新。

[编辑] 在建议使用 apply vs commit 作为依赖于内存缓存层的快速解决方法之后,结果证明 SharedPreferences 没有提供我们正在调整这个答案以使用本地广播接收器。

这应该有效,根据文档使用 commit() 或 apply() 。所有进程内线程和组件之间的更改应该立即可见。但是,我注意到 Android 过去试图在服务和 Activity 之间执行此操作时存在错误。让您尝试使用 getDefaultSharedPreferences() 而不是自定义文件。我使用默认文件没有遇到任何问题。

即使重新启动 activity 也无法在数据提交后获取数据。唯一做的就是完全重新启动应用程序。这是在 API 27.