Android DataStore:安全存储和轻松管理数据

打印 上一主题 下一主题

主题 971|帖子 971|积分 2913

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各范畴原创系列文章 ,善于java后端、移动开发、人工智能等,希望大家多多支持。
  
  

一、导读

我们继承总结学习Java底子知识,温故知新。
二、概览

DataStore 是一种用于 Android 应用程序数据存储的新的保举方式。
它是在 Android Jetpack 组件中引入的,旨在替代 SharedPreferences,并提供更强盛、易于利用的 API。
DataStore 基于 Kotlin 协程和 Flow 构建而成, 提供了一种类型安全且异步的数据存储解决方案。
相比于 SharedPreferences,DataStore 具有以下优点:

  • 异步操纵:DataStore 提供了异步的读写操纵,避免了壅闭主线程的题目。这使得在读取和写入数据时,应用程序可以更好地保持响应性能。
  • 类型安全:DataStore 支持利用协议缓冲区(Protocol Buffers)来定义数据模型,如许可以确保在编译时举行类型查抄。数据模型的更改不会导致运行时错误,而是在编译时举行检测。
  • 支持多种数据类型:DataStore 支持存储不同类型的数据,包括原始类型、对象或自定义类。
  • 数据同等性:DataStore 提供了同等性和安全性包管,包管在多个写入操纵中的数据同等性。
  • 流式数据访问:DataStore 支持利用流(Flow)来访问数据,使得可以轻松地观察数据的变革并举行相应的更新。
DataStore 提供了两个紧张的实现方式:PreferencesDataStore 和 ProtoDataStore。
PreferencesDataStore 实用于存储简朴的数据类型,利用键值对来存储数据。
ProtoDataStore 则利用 Protocol Buffers 定义数据模型,并支持存储更复杂的数据布局(类型化对象)。
三、利用

3.1 Preferences DataStore

实用于存储简朴的数据类型,利用键值对来存储数据
添加依靠

  1.     // Preferences DataStore (SharedPreferences like APIs)
  2.     dependencies {
  3.         implementation "androidx.datastore:datastore-preferences:1.0.0"
  4.         // optional - RxJava2 support
  5.         implementation "androidx.datastore:datastore-preferences-rxjava2:1.0.0"
  6.         // optional - RxJava3 support
  7.         implementation "androidx.datastore:datastore-preferences-rxjava3:1.0.0"
  8.     }
  9.     // Alternatively - use the following artifact without an Android dependency.
  10.     dependencies {
  11.         implementation "androidx.datastore:datastore-preferences-core:1.0.0"
  12.     }
  13.    
复制代码
数据读写

  1. RxDataStore<Preferences> dataStore =
  2.   new RxPreferenceDataStoreBuilder(context, /*name=*/ "settings").build();
  3. Preferences.Key<Integer> EXAMPLE_COUNTER = PreferencesKeys.int("example_counter");
  4. Flowable<Integer> exampleCounterFlow = dataStore.data().map(prefs -> prefs.get(EXAMPLE_COUNTER));
  5. Single<Preferences> updateResult =  dataStore.updateDataAsync(prefsIn -> {
  6.     MutablePreferences mutablePreferences = prefsIn.toMutablePreferences();
  7.     Integer currentInt = prefsIn.get(INTEGER_KEY);
  8.     mutablePreferences.set(INTEGER_KEY, currentInt != null ? currentInt + 1 : 1);
  9.     return Single.just(mutablePreferences);
  10. });
  11. // The update is completed once updateResult is completed.
复制代码
3.2 ProtoDataStore

利用 Protocol Buffers 定义数据模型,并支持存储更复杂的数据布局
添加依靠

  1.     // Typed DataStore (Typed API surface, such as Proto)
  2.     dependencies {
  3.         implementation "androidx.datastore:datastore:1.0.0"
  4.         // optional - RxJava2 support
  5.         implementation "androidx.datastore:datastore-rxjava2:1.0.0"
  6.         // optional - RxJava3 support
  7.         implementation "androidx.datastore:datastore-rxjava3:1.0.0"
  8.     }
  9.     // Alternatively - use the following artifact without an Android dependency.
  10.     dependencies {
  11.         implementation "androidx.datastore:datastore-core:1.0.0"
  12.     }
  13.    
复制代码
数据读写

Proto DataStore 要求在 app/src/main/proto/ 目录的 proto 文件中保存预定义的架构。
此架构用于定义在 Proto DataStore 中保存的对象的类型。
  1. syntax = "proto3";
  2. option java_package = "com.example.application";
  3. option java_multiple_files = true;
  4. message Settings {
  5.   int32 example_counter = 1;
  6. }
复制代码
  1. private static class SettingsSerializer implements Serializer<Settings> {
  2.   @Override
  3.   public Settings getDefaultValue() {
  4.     Settings.getDefaultInstance();
  5.   }
  6.   @Override
  7.   public Settings readFrom(@NotNull InputStream input) {
  8.     try {
  9.       return Settings.parseFrom(input);
  10.     } catch (exception: InvalidProtocolBufferException) {
  11.       throw CorruptionException(“Cannot read proto.”, exception);
  12.     }
  13.   }
  14.   @Override
  15.   public void writeTo(Settings t, @NotNull OutputStream output) {
  16.     t.writeTo(output);
  17.   }
  18. }
  19. RxDataStore<Byte> dataStore =
  20.     new RxDataStoreBuilder<Byte>(context, /* fileName= */ "settings.pb", new SettingsSerializer()).build();
  21. Flowable<Integer> exampleCounterFlow =
  22.         dataStore.data().map(settings -> settings.getExampleCounter());
  23. Single<Settings> updateResult = dataStore.updateDataAsync(currentSettings ->
  24.                 Single.just(
  25.                         currentSettings.toBuilder()
  26.                                 .setExampleCounter(currentSettings.getExampleCounter() + 1)
  27.                                 .build()));   
复制代码
3.3、在同步代码中利用 DataStore

DataStore 的紧张优势之一是异步 API,但可能不一定始终能将周围的代码更改为异步代码。如果您利用的现有代码库采取同步磁盘 I/O,大概您的依靠项不提供异步 API,就可能出现这种情况。
Kotlin 协程提供 runBlocking() 协程构建器,以资助消除同步与异步代码之间的差异。您可以利用 runBlocking() 从 DataStore 同步读取数据。RxJava 在 Flowable 上提供壅闭方法。以下代码会壅闭发起调用的线程,直到 DataStore 返回数据:
  1. Settings settings = dataStore.data().blockingFirst();
  2. dataStore.data().first().subscribe();
  3. 这样,DataStore 可以异步读取数据并将其缓存在内存中。以后使用 runBlocking() 进行同步读取的速度可能会更快,或者如果初始读取已经完成,可能也可以完全避免磁盘 I/O 操作。
复制代码


  • 请尽可能避免在 DataStore 数据读取时壅闭线程。壅闭界面线程可能会导致 ANR 或界面卡顿,而壅闭其他线程可能会导致死锁。
3.4、在多历程代码中利用 DataStore



  • DataStore 多历程功能目前仅在 1.1.0 Alpha 版中提供
为了可以大概在不同历程中利用 DataStore,需要利用 MultiProcessDataStoreFactory 构造 DataStore 对象。
  1. val dataStore: DataStore<Settings> = MultiProcessDataStoreFactory.create(
  2.    serializer = SettingsSerializer(),
  3.    produceFile = {
  4.        File("${context.cacheDir.path}/myapp.preferences_pb")
  5.    }
  6. )
复制代码
四、DataStore & MMKV

看一组数据对比,图片泉源于MMKV 开源网站


至于如何利用就不描述了,非常简朴。
个人感觉 DataStore 没有 MMKV 好用,保举利用 MMKV,但是各有优劣吧。
jetpack 官网
datastore
五、 保举阅读

Java 专栏
SQL 专栏
数据布局与算法
Android学习专栏

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

笑看天下无敌手

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表