在Android中,Shared Preferences的最佳替代方案是什么?

18

如果我想要读取数据并进行更改,那么在安卓中用来存储数据的最佳替代选项是什么?数据可以是用户资料、JSON响应或任何对象。 由于我存储了大量数据,我正在寻找其他耗时较少的选项来读取/写入数据。 目前,我的应用程序从活动A转到活动B需要x毫秒,我能否减少这个时间?


请详细解释“快速/安全交易”的含义,并澄清为何SharedPreferences不符合您的需求。 - CommonsWare
@CommonsWare详细解答了我的问题。 - Mr.India
6个回答

22

没有深入了解您的使用情况,很难为您推荐适合的方案。

  • 如果您想存储一些用户喜好数据 - SharedPreferences 可能是一个不错的选择。
  • 如果您想存储身份验证数据,例如用户的身份验证令牌,请不要使用 SharedPreferences,而应查看 AccountManager
  • 如果您想存储业务数据,例如多个业务实体之间的某些关系,并希望能够对其进行查询和/或修改 - 我建议您使用 Realm - https://realm.io。作为替代品,可以使用 SQLite,但我非常主观地认为 Realm 更容易上手。
  • 如果您只想缓存一些基于 JSON 的响应,请查看您的 HTTP 客户端可能提供的缓存机制。例如,OkHttp 对此有相当好的支持。

谈到加载时间 - SharedPreferences 总体来说速度相当快,但这确实取决于您如何使用它。如果您将大型 JSON 结构存储在其中,然后完全读取它仅基于 id 查找某个特定对象 - 显然,这比使用真正的数据库要花费更多的时间。

请注意,我提出的所有解决方案(AccountManagerSharedPreferences 和 SQLite/Realm)都可以在一个应用程序中完美地协同工作。只需确保为给定问题选择适当的工具即可。


领域是否安全存储认证令牌? - Dinesh

11

Jetpack DataStore 是一个新的、改进的数据存储解决方案,旨在取代 SharedPreferences。基于 Kotlin 协程和 Flow 构建,DataStore 提供了两种不同的实现方式:

数据以异步、一致和事务性的方式存储,克服了 SharedPreferences 大部分的缺点。

如果您目前正在使用 SharedPreferences 存储数据,请考虑迁移到 DataStore。

DataStore 的类型

DataStore 提供了两种不同的实现方式:

Preferences DataStore - 使用键存储和访问数据。这种实现不需要预定义模式,也不提供类型安全性。

Proto DataStore - 将数据存储为自定义数据类型的实例。这种实现需要使用协议缓冲区定义模式,但它提供了类型安全性。

SharedPreferences vs DataStore

SharedPreference 在 apply() 调用预定的 fsync() 期间会阻塞 UI 线程,常常成为 ANR 的来源。

SharedPreferences 会将解析错误作为运行时异常抛出。

在这两种实现中,DataStore 将首选项保存在文件中,并在 Dispatchers.IO 线程上执行所有数据操作。

参考:DataStore - Jetpack Alternative For SharedPreference


1
这个链接突出了SharedPreferences和Jet DataStore之间的区别:https://android-developers.googleblog.com/2020/09/prefer-storing-data-with-jetpack.html - Fahima Mokhtari

2

如果有大量数据需要存储,那么不应该使用Shared Preferences,因为这样会很混乱。相反,您应该写入内部存储。以下是您的选项:

**Shared Preferences**
Store private primitive data in key-value pairs.
**Internal Storage**
Store private data on the device memory.
**External Storage**
Store public data on the shared external storage.
**SQLite Databases**
Store structured data in a private database.
**Network Connection**
Store data on the web with your own network server.

最后三个步骤是最困难的,但前两个步骤非常容易。如果您在共享首选项中有太多数据,则可以按如下方式存储到内部存储中:
注意:当用户卸载您的应用程序时,这些文件将被删除。从文档中得知:
要创建和写入一个私有文件到内部存储器:
1. 使用文件名和操作模式调用openFileOutput()。
2. 这将返回一个FileOutputStream。
3. 使用write()向文件中写入数据。
4. 用close()关闭流。
例如:
String FILENAME = "hello_file";
String string = "hello world!";

FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();

读取数据也非常简单: 1. 调用openFileInput()并传递要读取的文件名。 这将返回一个FileInputStream。 2. 使用read()从文件中读取字节。 3. 然后使用close()关闭流。 Shared preferences适用于存储简单的键值对,例如高分,用户设置等。 如果要保存用户输入的文章,则可以使用外部或内部存储。
如果有帮助,请让我知道。
Ruchir

1
如果您因为自动备份的危险而寻找替代方案,有一种方法可以从自动备份功能中排除您使用的特定SharedPrefs - 这可以通过在xml文件中声明排除标签,然后在您的清单文件的应用程序标记下使用android:fullBackupContent属性来引用它来实现。 这样做可以仍然支持自动备份功能,而不必担心存储在Google Drive云上的敏感信息。
好的参考资料: https://developer.android.com/guide/topics/data/autobackup.html https://www.youtube.com/watch?v=HXacyy0HSW0

0

我找不到更好的方法来保存用户数据。SharedPreferences 就是为此目的而制作的。SharedPreferences 不应该阻止您的活动加载。因此,可能有其他降低性能的原因。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接