1.共享参数的用法
SharedPreferences是Android的一个轻量级存储工具,它采用的存储结构是Key-Value的键值对方式,存储介质是XML文件,保存共享参数键值对信息的路径为/data/data/应用包名/shared_prefs/文件名.xml。下面是一个共享参数的XML文件例子:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="name">Mr Lee</string>
<int name="age" value="30" />
<boolean name="married" value="true" />
<float name="weight" value="100.0" />
</map>
基于xml格式的特点,共享参数主要用于如下场合:
(1)简单且孤立的数据
(2)文本形式的数据
(3)需要持久化存储的数据,APP退出之后再次启动时,之前保存的数据仍然有效
共享参数对数据的存储和读取操作类似于Map,也有存储数据的put方法,以及读取数据的get方法,调用getSharedPreferences方法可以获得共享参数实例,获取代码示例如下:
//从share.xml获取共享参数实例
SharedPreferences mShared = getSharedPreferences("share", MODE_PRIVATE);
由以上代码可知,getSharedPreferences方法的第一个参数是文件名,填share表示共享参数的文件名是share.xml;第二个参数是操作模式,填MODE_PRIVATE表示私有模式。
共享参数的存储要借助Editor类,保存数据的代码示例如下
SharedPreferences.Editor editor = mShared.edit(); // 获得编辑器的对象
editor.putString("name", name); // 添加一个名叫name的字符串参数
editor.putInt("age", Integer.parseInt(age)); // 添加一个名叫age的整型参数
editor.putLong("height", Long.parseLong(height)); // 添加一个名叫height的长整型参数
editor.putFloat("weight", Float.parseFloat(weight)); // 添加一个名叫weight的浮点数参数
editor.putBoolean("married", isMarried); // 添加一个名叫married的布尔型参数
editor.putString("update_time", DateUtil.getNowDateTime("yyyy-MM-dd HH:mm:ss"));
editor.commit(); // 提交编辑器中的修改
上述代码采用了commit方法提交修改,该方法会把数据直接写入磁盘,如果想要更好的性能,可将commit方法改为apply方法,该方法的提交操作会先将数据写入内存,然后异步把数据写入磁盘。
从共享参数读取数据
shared.getString(key, ""));
shared.getInt(key, 0));
shared.getFloat(key, 0.0f));
shared.getBoolean(key, false));
shared.getLong(key, 0L));
虽然SharedPreferences用起来比较方便,但是当保存数据较多时,初始化共享参数会把整个文件加载进内存,加载耗时可能导致主线程堵塞。又如在调用apply方法保存数据时,频繁apply容易导致线程等待超时。为此Android官方推出了数据仓库DataStore,并将其作为Jetpack库的基础组件。DataStore提供了两种实现方式,分别是Preferences DataStore和Proto DataStore,前者采用键值对存储数据,后者采用自定义类型存储数据。其中Preferences和DataStore可以替代SharedPreferences。
由于DataStore并未集成到SDK中,而是作为第三方框架提供,因此首先要修改模块的build.gradle文件,往dependencies节点添加下面两行配置,表示导入指定版本的DataStore库:
// datastore库各版本见 https://mvnrepository.com/artifact/androidx.datastore/datastore-preferences
implementation 'androidx.datastore:datastore-preferences:1.0.0'
// datastore库各版本见 https://mvnrepository.com/artifact/androidx.datastore/datastore-rxjava2
implementation 'androidx.datastore:datastore-preferences-rxjava2:1.0.0'
数据仓库的用法类似于共享参数,首先要指定仓库名称,并创建仓库实例,示例代码如下:
private RxDataStore<Preferences> mDataStore; // 声明一个数据仓库实例
private DatastoreUtil(Context context) {
mDataStore = new RxPreferenceDataStoreBuilder(context.getApplicationContext(), "datastore").build();
}
// 获取数据仓库工具的实例
public static DatastoreUtil getInstance(Context context) {
if (instance == null) {
instance = new DatastoreUtil(context);
}
return instance;
}
其次从仓库实例中获取指定键名的数据,下面的代码模板演示了如何从数据仓库中读取字符串值:
// 获取指定名称的字符串值
public String getStringValue(String key) {
Preferences.Key<String> keyId = PreferencesKeys.stringKey(key);
Flowable<String> flow = mDataStore.data().map(prefs -> prefs.get(keyId));
try {
return flow.blockingFirst();
} catch (Exception e) {
return "";
}
}
往仓库写入指定键值
// 设置指定名称的字符串值
public void setStringValue(String key, String value) {
Preferences.Key<String> keyId = PreferencesKeys.stringKey(key);
Single<Preferences> result = mDataStore.updateDataAsync(prefs -> {
MutablePreferences mutablePrefs = prefs.toMutablePreferences();
//String oldValue = prefs.get(keyId);
mutablePrefs.set(keyId, value);
return Single.just(mutablePrefs);
});
}