前言
各位同学大家好 有段时间没有给大家更新文章了, 具体多久我也记不清楚了哈 。 今天是大年初四 ,还在休假中。最近在学习iOS 开发 , 了解了iOS中的轻量级数据缓存的(之前做安卓和flutter 开发的 )所以今天趁着有时间就把IOS 端 Android端 flutter 跨端的轻量级数据缓存做一个对比分享给大家 那么废话不多说 我们正式开始
准备工作
-
iOS
安装xcode 这个大家可以自己去appstore 搜索下载安装即可
-
android
安卓这边需要安装AS(android studio)和jdk 然后配置环境变量即可
-
flutter
需要安装flutter的开发环境:大家可以去看看之前的教程:
1 win系统flutter开发环境安装教程: https://www.jianshu.com/p/152447bc8718
2 mac系统flutter开发环境安装教程:https://www.jianshu.com/p/bad2c35b41e3
具体实现:
-
iOS
在iOS 中我们存储轻量级数据的 例如登录的token还有 账号密码等等 轻量级数据的时候我们是用到了ios提供的 NSUserDefault来存储数据
NSUserDefault 的特点
提供了简单的key -value 存储
- 单例,存取轻量级的数据
- 一般用于用户偏好设置
- 升级安装后还可以继续使用
- 文件存储在/Library/Preferences 下
- 支持基本数据类型
- 保存 Interger Float Double Bool
- 保存NSArray NSData NSString NSDictionary
- 复杂Model 需要转化成NSData
系统提供的方法
- (void)setObject:(nullable id)value forKey:(NSString *)defaultName;
- (void)removeObjectForKey:(NSString *)defaultName;
- (nullable NSString *)stringForKey:(NSString *)defaultName;
- (nullable NSArray *)arrayForKey:(NSString *)defaultName;
- (nullable NSDictionary<NSString *, id> *)dictionaryForKey:(NSString *)defaultName;
- (nullable NSData *)dataForKey:(NSString *)defaultName;
- (nullable NSArray<NSString *> *)stringArrayForKey:(NSString *)defaultName;
- (NSInteger)integerForKey:(NSString *)defaultName;
- (float)floatForKey:(NSString *)defaultName;
- (double)doubleForKey:(NSString *)defaultName;
- (BOOL)boolForKey:(NSString *)defaultName;
具体代码调用
- 存数据
NSString * str=@"abd";
//存数据
[[NSUserDefaults standardUserDefaults] setObject:str forKey:@"test"];
- 取数据
NSString * test= [[NSUserDefaults standardUserDefaults]stringForKey:@"test"];
NSLog(@"test = %@", test);
-
效果
其他类型数据大家可以参考api方法自己去多尝试
android
android 中我们主要是用 Sharedpreferences 来实现轻量级数据的存储
Sharedpreferences是Android平台上一个轻量级的存储类,用来保存应用程序的各种配置信息,其本质是一个以“键-值”对的方式保存数据的xml文件,其文件保存在/data/data//shared_prefs目录下。在全局变量上看,其优点是不会产生Application 、 静态变量的OOM(out of memory)和空指针问题,其缺点是效率没有上面的两种方法高。
具体使用
-
1.获取SharedPreferences
要想使用 SharedPreferences 来存储数据,首先需要获取到 SharedPreferences 对象。Android中主要提供了三种方法用于得到 SharedPreferences 对象。
1. Context 类中的 getSharedPreferences()方法:
此方法接收两个参数,第一个参数用于指定 SharedPreferences 文件的名称,如果指定的文件不存在则会创建一个,第二个参数用于指定操作模式,主要有以下几种模式可以选择。MODE_PRIVATE 是默认的操作模式,和直接传入 0 效果是相同的。
MODE_WORLD_READABLE 和 MODE_WORLD_WRITEABLE 这两种模式已在 Android 4.2 版本中被废弃。
Context.MODE_PRIVATE: 指定该SharedPreferences数据只能被本应用程序读、写;
Context.MODE_WORLD_READABLE: 指定该SharedPreferences数据能被其他应用程序读,但不能写;
Context.MODE_WORLD_WRITEABLE: 指定该SharedPreferences数据能被其他应用程序读;
Context.MODE_APPEND:该模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件;
- Activity 类中的 getPreferences()方法:
这个方法和 Context 中的 getSharedPreferences()方法很相似,不过它只接收一个操作模式参数,因为使用这个方法时会自动将当前活动的类名作为 SharedPreferences 的文件名。 - PreferenceManager 类中的 getDefaultSharedPreferences()方法:
这是一个静态方法,它接收一个 Context 参数,并自动使用当前应用程序的包名作为前缀来命名 SharedPreferences 文件。
-
SharedPreferences的使用
SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过SharedPreferences.edit()获取的内部接口Editor对象实现。使用Preference来存取数据,用到了SharedPreferences接口和SharedPreferences的一个内部接口SharedPreferences.Editor,这两个接口在android.content包中;
SharedPreferences 存数据
- 1调用 源码中 ContextWrapper中的 getSharedPreferences 方法给SharedPreferences 创建一个实例
//步骤1:创建一个SharedPreferences对象
SharedPreferences sharedPreferences= getSharedPreferences("data",Context.MODE_PRIVATE);
- 2 实例化SharedPreferences.Editor对象并调用Editor 对象里面方法存数据
//步骤2: 实例化SharedPreferences.Editor对象
SharedPreferences.Editor editor = sharedPreferences.edit();
//步骤3:将获取过来的值放入文件
editor.putString("name", “xuqing”);
editor.putInt("age", 28);
editor.putBoolean("marrid",false);
//步骤4:提交
editor.commit();
SharedPreferences取数据
读取数据:
SharedPreferences sharedPreferences= getSharedPreferences("data", Context .MODE_PRIVATE);
String userId=sharedPreferences.getString("name","");
删除数据(删除指定数据)
删除指定数据
editor.remove("name");
editor.commit();
清空数据
清空数据
editor.clear();
editor.commit();
注意:如果在 Fragment 中使用SharedPreferences 时,需要放在onAttach(Activity activity)里面进行SharedPreferences的初始化,否则会报空指针 即 getActivity()会可能返回null !
editor提供的对外方法
public interface Editor {
Editor putString(String key, @Nullable String value);
Editor putStringSet(String key, @Nullable Set<String> values);
Editor putInt(String key, int value);
Editor putLong(String key, long value);
Editor putFloat(String key, float value);
Editor putBoolean(String key, boolean value);
Editor remove(String key);
Editor clear();
boolean commit();
void apply();
}
从源码里面 editor 提供的方法来看 我们的SharedPreferences 轻量级缓存 能够存储的数据只支持基本数据类型 (int long float Boolean ) 和string 引用类型 并不能存一个对象 bean这种复杂的数据类型 我们要对SharedPreferences 做些简单的封装就能满足我们的需求 不过我们始终要清楚 SharedPreferences 只适合轻量级数据 如果数据过多不建议使用这种方式
我们对 SharedPreferences 做一些简单封装来满足我们的各种需求
-
存数据 取数据 删除数据的封装
private static final String TAG = "SharedPreferencesUtils";
/**
* 保存在手机里面的文件名
*/
private static final String FILE_NAME = "test";
private static SharedPreferences sp;
/**
* 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
*
* @param context
* @param key
* @param object
* @param :SharedPreferencesUtils.setParam(this, "key", "value");
* key -- userid / accountId obj==
*/
public static void setParam(Context context, String key, Object object) {
String type = "String";
if (object != null) {
type = object.getClass().getSimpleName();
}
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
if ("String".equals(type)) {
editor.putString(key, (String) object);
} else if ("Integer".equals(type) || "int".equals(type)) {
editor.putInt(key, (Integer) object);
} else if ("Boolean".equals(type) || "boolean".equals(type)) {
editor.putBoolean(key, (Boolean) object);
} else if ("Float".equals(type) || "float".equals(type)) {
editor.putFloat(key, (Float) object);
} else if ("Long".equals(type) || "long".equals(type)) {
editor.putLong(key, (Long) object);
}
editor.commit();
}
/**
* 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
*
* @param context
* @param key 关键字
* @param defaultObject 若取回空值则返回此默认值
* @param :SharedPreferencesUtils.getParam(Activity.this, "key", "defaultValue");
* @return
*/
public static Object getParam(Context context, String key, Object defaultObject) {
String type = "String";
if (defaultObject != null) {
type = defaultObject.getClass().getSimpleName();
}
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, MODE_PRIVATE);
if ("String".equals(type)) {
return sp.getString(key, (String) defaultObject);
} else if ("Integer".equals(type) || "int".equals(type)) {
return sp.getInt(key, (Integer) defaultObject);
} else if ("Boolean".equals(type) || "boolean".equals(type)) {
return sp.getBoolean(key, (Boolean) defaultObject);
} else if ("Float".equals(type) || "float".equals(type)) {
return sp.getFloat(key, (Float) defaultObject);
} else if ("Long".equals(type) || "long".equals(type)) {
return sp.getLong(key, (Long) defaultObject);
}
return null;
}
//删除指定的key
public static void removeParam(Context context, String key, Object defaultObject) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.remove(key);
editor.commit();
}
-
存list
/**
* 4.存储账本bookBean的list
*/
public static void putSelectBean(Context context, List<SelectPhone> phoneList, String key) {
if (sp == null) {
sp = context.getSharedPreferences("config", MODE_PRIVATE);
}
SharedPreferences.Editor editor = sp.edit();
Gson gson = new Gson();
String json = gson.toJson(phoneList);
editor.putString(key, json);
editor.commit();
}
/**
* 读取账本SelectPhone的list
*/
public static List<SelectPhone> getSelectBean(Context context, String key) {
if (sp == null) {
sp = context.getSharedPreferences("config", MODE_PRIVATE);
}
Gson gson = new Gson();
String json = sp.getString(key, null);
Log.e(TAG, "getSelectBean: json >>> " + json);
Type type = new TypeToken<List<SelectPhone>>() {
}.getType();
List<SelectPhone> arrayList = gson.fromJson(json, type);
return arrayList;
}
-
缓存map集合
//缓存map集合
public static void putHashMapData(Context context, String key, Map<String, Object> datas) {
JSONArray mJsonArray = new JSONArray();
Iterator<Map.Entry<String, Object>> iterator = datas.entrySet().iterator();
JSONObject object = new JSONObject();
while (iterator.hasNext()) {
Map.Entry<String, Object> entry = iterator.next();
try {
object.put(entry.getKey(), entry.getValue());
} catch (JSONException e) {
}
}
mJsonArray.put(object);
SharedPreferences sp = context.getSharedPreferences("config",
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString(key, mJsonArray.toString());
editor.commit();
}
//获取map缓存数据
public static Map<String, Object> getHashMapData(Context context, String key) {
Map<String, Object> datas = new HashMap<>();
SharedPreferences sp = context.getSharedPreferences("config",
Context.MODE_PRIVATE);
String result = sp.getString(key, "");
try {
JSONArray array = new JSONArray(result);
for (int i = 0; i < array.length(); i++) {
JSONObject itemObject = array.getJSONObject(i);
JSONArray names = itemObject.names();
if (names != null) {
for (int j = 0; j < names.length(); j++) {
String name = names.getString(j);
String value = itemObject.getString(name);
datas.put(name, value);
}
}
}
} catch (JSONException e) {
}
return datas;
}
-
存储到SD卡(这里顺带讲一下 Android 里面 Android 6.0 以后要申请权限再操作SD 存储)
//存数据到SD卡里面
public static void storetosd(File file, List<SelectPhone> data) {
try {
Gson gson = new Gson();
String json = gson.toJson(data);
OutputStream os = new FileOutputStream(file);
os.write(json.getBytes("utf-8"));
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//读取SD卡里面的数据
public static List<SelectPhone> readbysd(File file) {
List<SelectPhone> arrayList = null;
Gson gson = new Gson();
try {
InputStream is = new FileInputStream(file);
byte[] data = new byte[is.available()];
is.read(data);
String content = new String(data, "utf-8");
Type type = new TypeToken<List<SelectPhone>>() {
}.getType();
arrayList = gson.fromJson(content, type);
is.close();
} catch (Exception e) {
e.printStackTrace();
}
return arrayList;
}
完整代码演示
package com.shiyue.game.utils;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.shiyue.game.bean.SelectPhone;
import com.shiyue.game.utils.log.LeLanLog;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import static android.content.Context.MODE_PRIVATE;
/**
* SharedPreferences的一个工具类
* 使用方法:
* 调用setParam就能保存String, Integer, Boolean, Float, Long类型的参数
* SharedPreferencesUtils.setParam(this, "String", "xiaanming");
* SharedPreferencesUtils.setParam(this, "int", 10);
* SharedPreferencesUtils.setParam(this, "boolean", true);
* SharedPreferencesUtils.setParam(this, "long", 100L);
* SharedPreferencesUtils.setParam(this, "float", 1.1f);
* <p>
* 同样调用getParam就能获取到保存在手机里面的数据
* SharedPreferencesUtils.getParam(Activity.this, "String", "");
* SharedPreferencesUtils.getParam(Activity.this, "int", 0);
* SharedPreferencesUtils.getParam(Activity.this, "boolean", false);
* SharedPreferencesUtils.getParam(Activity.this, "long", 0L);
* SharedPreferencesUtils.getParam(Activity.this, "float", 0.0f);
*
* @author xuqing
*/
public class SharedPreferencesUtils {
private static final String TAG = "SharedPreferencesUtils";
/**
* 保存在手机里面的文件名
*/
private static final String FILE_NAME = "test";
private static SharedPreferences sp;
/**
* 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
*
* @param context
* @param key
* @param object
* @param :SharedPreferencesUtils.setParam(this, "key", "value");
* key -- userid / accountId obj==
*/
public static void setParam(Context context, String key, Object object) {
String type = "String";
if (object != null) {
type = object.getClass().getSimpleName();
}
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
if ("String".equals(type)) {
editor.putString(key, (String) object);
} else if ("Integer".equals(type) || "int".equals(type)) {
editor.putInt(key, (Integer) object);
} else if ("Boolean".equals(type) || "boolean".equals(type)) {
editor.putBoolean(key, (Boolean) object);
} else if ("Float".equals(type) || "float".equals(type)) {
editor.putFloat(key, (Float) object);
} else if ("Long".equals(type) || "long".equals(type)) {
editor.putLong(key, (Long) object);
}
editor.commit();
}
/**
* 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
*
* @param context
* @param key 关键字
* @param defaultObject 若取回空值则返回此默认值
* @param :SharedPreferencesUtils.getParam(Activity.this, "key", "defaultValue");
* @return
*/
public static Object getParam(Context context, String key, Object defaultObject) {
String type = "String";
if (defaultObject != null) {
type = defaultObject.getClass().getSimpleName();
}
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, MODE_PRIVATE);
if ("String".equals(type)) {
return sp.getString(key, (String) defaultObject);
} else if ("Integer".equals(type) || "int".equals(type)) {
return sp.getInt(key, (Integer) defaultObject);
} else if ("Boolean".equals(type) || "boolean".equals(type)) {
return sp.getBoolean(key, (Boolean) defaultObject);
} else if ("Float".equals(type) || "float".equals(type)) {
return sp.getFloat(key, (Float) defaultObject);
} else if ("Long".equals(type) || "long".equals(type)) {
return sp.getLong(key, (Long) defaultObject);
}
return null;
}
//删除指定的key
public static void removeParam(Context context, String key, Object defaultObject) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.remove(key);
editor.commit();
}
/**
* 4.存储账本bookBean的list
*/
public static void putSelectBean(Context context, List<SelectPhone> phoneList, String key) {
if (sp == null) {
sp = context.getSharedPreferences("config", MODE_PRIVATE);
}
SharedPreferences.Editor editor = sp.edit();
Gson gson = new Gson();
String json = gson.toJson(phoneList);
editor.putString(key, json);
editor.commit();
}
/**
* 读取账本SelectPhone的list
*/
public static List<SelectPhone> getSelectBean(Context context, String key) {
if (sp == null) {
sp = context.getSharedPreferences("config", MODE_PRIVATE);
}
Gson gson = new Gson();
String json = sp.getString(key, null);
Log.e(TAG, "getSelectBean: json >>> " + json);
Type type = new TypeToken<List<SelectPhone>>() {
}.getType();
List<SelectPhone> arrayList = gson.fromJson(json, type);
return arrayList;
}
//缓存map集合
public static void putHashMapData(Context context, String key, Map<String, Object> datas) {
JSONArray mJsonArray = new JSONArray();
Iterator<Map.Entry<String, Object>> iterator = datas.entrySet().iterator();
JSONObject object = new JSONObject();
while (iterator.hasNext()) {
Map.Entry<String, Object> entry = iterator.next();
try {
object.put(entry.getKey(), entry.getValue());
} catch (JSONException e) {
}
}
mJsonArray.put(object);
SharedPreferences sp = context.getSharedPreferences("config",
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString(key, mJsonArray.toString());
editor.commit();
}
//获取map缓存数据
public static Map<String, Object> getHashMapData(Context context, String key) {
Map<String, Object> datas = new HashMap<>();
SharedPreferences sp = context.getSharedPreferences("config",
Context.MODE_PRIVATE);
String result = sp.getString(key, "");
try {
JSONArray array = new JSONArray(result);
for (int i = 0; i < array.length(); i++) {
JSONObject itemObject = array.getJSONObject(i);
JSONArray names = itemObject.names();
if (names != null) {
for (int j = 0; j < names.length(); j++) {
String name = names.getString(j);
String value = itemObject.getString(name);
datas.put(name, value);
}
}
}
} catch (JSONException e) {
}
return datas;
}
//存数据到SD卡里面
public static void storetosd(File file, List<SelectPhone> data) {
try {
Gson gson = new Gson();
String json = gson.toJson(data);
OutputStream os = new FileOutputStream(file);
os.write(json.getBytes("utf-8"));
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//读取SD卡里面的数据
public static List<SelectPhone> readbysd(File file) {
List<SelectPhone> arrayList = null;
Gson gson = new Gson();
try {
InputStream is = new FileInputStream(file);
byte[] data = new byte[is.available()];
is.read(data);
String content = new String(data, "utf-8");
Type type = new TypeToken<List<SelectPhone>>() {
}.getType();
arrayList = gson.fromJson(content, type);
is.close();
} catch (Exception e) {
e.printStackTrace();
}
return arrayList;
}
/**
* 获得账号数组形式的列表(字符串转数组)
* 通过参数确认是否需要翻转排序输出
*
* @param context
* @param isReverse
* @return
*/
public static ArrayList getSYAccountList(Context context, boolean isReverse) {
if (!getSYAccountArray(context).equals("")) {
String temp = getSYAccountArray(context);
LeLanLog.d("getSYAccountList 已缓存 账号列表 accountList=" + temp);
String[] arrString = temp.split("#");
ArrayList b = new ArrayList();
for (int i = 0; i <= arrString.length - 1; i++) {
b.add(arrString[i]);
}
if (isReverse) {
ArrayList c = b;
Collections.reverse(c);
return c;
} else {
return b;
}
} else {
return null;
}
}
/**
* 获取账号列表
*
* @param context
* @return
*/
public static String getSYAccountArray(Context context) {
String temp = "";
SharedPreferences data = context.getSharedPreferences("account_file_name", 0);
temp = data.getString("array", "");
LeLanLog.d("getSYAccountArray 从账号文件中读取账号数组 array=" + temp);
String arraylist = BaseUtil.decode(temp);
return arraylist;
}
/**
* 通过账号列表获取到详细用户信息
*
* @param context
* @param account
* @return
*/
public static HashMap getUserInfo(Context context, String account) {
String key = BaseUtil.encode(account.getBytes());
SharedPreferences userData = context.getSharedPreferences(key, 0);
String muid = userData.getString("account", "");
String mpwd = userData.getString("pwd", "");
String mphoneNum = userData.getString("phoneNum", "");
String mlonginTicket = userData.getString("longinToken", "");
String muserName = userData.getString("userName", "");
String mloginType = userData.getString("loginType", "");
String mnickName = userData.getString("nickName", "");
String mloginTimes = userData.getString("loginTimes", "");
HashMap hs = new HashMap();
hs.put("account", BaseUtil.decode(muid));
hs.put("pwd", BaseUtil.decode(mpwd));
hs.put("phoneNum", BaseUtil.decode(mphoneNum));
hs.put("longinToken", BaseUtil.decode(mlonginTicket));
hs.put("userName", BaseUtil.decode(muserName));
hs.put("loginType", BaseUtil.decode(mloginType));
hs.put("mnickName", BaseUtil.decode(mnickName));
hs.put("loginTimes", BaseUtil.decode(mloginTimes));
Log.d("loginTimes2=", BaseUtil.decode(mloginTimes));
return hs;
}
}
更多的android 里面SharedPreferences 用法 大家可以查阅官方API 这边就不再深入了
-
flutter
原生iOS 和原生android 里面的轻量级数据缓存我们都讲了 在原生的andriod 和iOS 里面都会有数据缓存的api Android 端用的是 Sharedpreferences 来实现对于轻量级数据的缓存 , IOS端 通常使用NSUserDefaults 来实现轻量级数据的缓存 但是在flutter 有基于Android iOS 做支持的三方插件库 shared_preferences ,其实shared_preferences 这个库本身底层是基于(android ) Sharedpreferences 和(ios)NSUserDefaults 封装的
我们普通开发者在上层调用API即可
shared_preferences 使用准备工作
shared_preferences: ^0.5.3+4
在项目里面的pubspec.yaml 添加依赖 然后在项目根目录打开控制台输入 flutter pub get 命令回去下载相对应的依赖
shared_preferences基本用法
存储基本数据类型:
int 类型
onPressed: ()async{
SharedPreferences prefs = await SharedPreferences.getInstance();
int counter = 1;
await prefs.setInt('counter', counter);
},
String类型
onPressed: ()async{
SharedPreferences prefs = await SharedPreferences.getInstance();
String counter = "1";
await prefs.setString('counter', counter);
},
bool类型
onPressed: ()async{
SharedPreferences prefs = await SharedPreferences.getInstance();
bool counter =false;
await prefs.setBool('counter', counter);
},
double类型
onPressed: ()async{
SharedPreferences prefs = await SharedPreferences.getInstance();
double counter =0.01;
await prefs.setDouble('counter', counter);
},
list<String>data类型
onPressed: ()async{
SharedPreferences prefs = await SharedPreferences.getInstance();
List<String>counter=["1","2"];
await prefs.setStringList('counter', counter);
},
取值基本用法
onPressed: ()async{
SharedPreferences prefs = await SharedPreferences.getInstance();
int counterint =prefs.getInt("counter");
String counter =prefs.getString("counter");
bool counterbool =prefs.getBool("counter");
double counterdouble =prefs.getDouble("counter");
List counterlist =prefs.getStringList("counter");
},
删除指定数据
其中key就是你存贮的名称,value就是你存储的值
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.remove(key); //删除指定键
清空整个缓存:
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.clear();//清空键值对
以上是Sharedpreferences 的基础用法 ,但是我们发现没有每次写一大推重复代码 这时候我们就对Sharedpreferences 进行简单封装是我们减少重复代码的编写
/***
*
* 存数据
*/
static Object savePreference(BuildContext context , String key , Object value) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
if(value is int ){
await prefs.setInt(key, value);
}else if(value is double){
await prefs.setDouble(key, value);
}else if(value is bool){
await prefs.setBool(key, value);
}else if(value is String){
await prefs.setString(key, value);
}else if(value is List){
await prefs.setStringList(key, value);
} else {
throw new Exception("不能得到这种类型");
}
}
/***
* 取数据
*
*/
static Future getPreference( Object context , String key ,Object defaultValue) async{
SharedPreferences prefs = await SharedPreferences.getInstance();
if(defaultValue is int) {
return prefs.getInt(key);
}
else if(defaultValue is double) {
return prefs.getDouble(key);
}
else if(defaultValue is bool) {
return prefs.getBool(key);
}
else if(defaultValue is String) {
return prefs.getString(key);
}
else if(defaultValue is List) {
return prefs.getStringList(key);
}
else {
throw new Exception("不能得到这种类型");
}
}
/***
* 删除指定数据
*/
static void remove(String key)async{
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.remove(key); //删除指定键
}
/***
* 清空整个缓存
*/
static void clear()async{
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.clear(); ////清空缓存
}
工具类具体调用 :
存储数据:
onPressed: (){
String counter = "1";
SharedPreferencesUtils.savePreference(context, "counter", counter);
},
),
取值
直接调用并赋值给定义的变量
onPressed: ()async{
String counter = await (SharedPreferencesUtils.getPreference(context, "counter", "1")) as String ;
print("counter -- > "+counter);
},
通过then方式调用
onPressed: ()async{
SharedPreferencesUtils.getPreference(context, "counter", "1").then((value){
print("value --->" +value);
});
},
删除指定key的缓存数据调用:
SharedPreferencesUtils.remove("counter");
清空整个SharedPreferences缓存:
SharedPreferencesUtils.clear();
基本数据类型的封装使用我们就说完了 大家发现没有有时候我们需要存一个model其实
SharedPreferences 本身是不支持我们要怎么做
如上图是我们需要把用户名和密码起来保存 我们用传统 SharedPreferences 来做肯定不OK 当然有同学肯定想到说用 sqlite 本地数据库来实现 ,sqlite 确实可以实现 但是本身代码就多不够灵活 而且我们这边存储的字段并不多 我们这边选择在 SharedPreferences 上面做稍微的改造就能实现上面的需求的
之前的实现方式 :
onPressed: ()async{
User user=new User();
user.username=_username;
user.password=_password;
datalsit.add(user);
String jsonStringA = jsonEncode(datalsit);
print("jsonStringA --------- >"+ jsonStringA);
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString("data",jsonStringA);
},
取值转换
onPressed: ()async{
SharedPreferences prefs = await SharedPreferences.getInstance();
getdata = await prefs.getString("data");
List list= json.decode(getdata);
},
获取到值以后我们要通过 json.decode 将那倒json字符串转成list然后再来取值,这是我们传统的做法 代码量其实很大 而且如果我们有很多类似的数据要存储肯定做法不够简洁 我们这里也对于之前实现方式简单的封装 代码如下
/**
* 存储 List<Object> phoneList
*
* List<Object> phoneList
*/
static void setSelectBeanList(BuildContext context,List<Object> phoneList, String key) async{
String jsonStringA = jsonEncode(phoneList);
print("jsonStringA --------- >"+ jsonStringA);
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString(key,jsonStringA);
}
/**
* 获取 List<Object> phoneList
*
* List<Object> phoneList
*/
static Future getSelectBean(BuildContext context, String key) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String getdata = await prefs.getString("data");
List list= json.decode(getdata);
return list;
}
具体调用:
存储model:
onPressed: ()async{
User user=new User();
user.username=_username;
user.password=_password;
_userlsit.add(user);
SharedPreferencesUtils.setSelectBeanList(context, _userlsit, "data");
},
取值:
onPressed: ()async{
List datalist= await SharedPreferencesUtils.getSelectBean(context, "data");
},
到此整个 SharedPreferences库 数据存储的基础用法和特别技巧我们就讲完了。
最后总结
无论是原生IOS 还是原生Android系统都提供了 轻量级缓存数据 api 方法 供我们开发者调用,无论是iOS的 NSUserDefaults 还是 Android 的Sharedpreferences 都定位住轻量级数据缓存 存储的数据类型也就是基本类型 复杂的类型我们也要通过转换才能存储和取值 还有就是 Sharedpreferences 和 NSUserDefaults 这两端的轻量级缓存 不卸载app 或者你主动掉调用方法删除 数据都可以保住 更新覆盖安装也能保住 所以是比较适合我们日常app 开发的一些轻量级数据存储 例如用户token 用户偏好 账号密码等等 , flutter 作为后起之秀的跨平台方案 我们使用了 shared_preferences 这个三方库 (和Android名字很像哈)就是底层使NSUserDefaults 和 Sharedpreferences 分别IOS 端和Android 端做了封装支持 所以我们上层开发者无需担心使用问题 写这期博客也是为了让那些非原生转flutter的同学对于 flutter里面数据存储对比原生有一个更加清楚认知。最后希望我的文章能帮助到各位解决问题 ,以后我还会贡献更多有用的代码分享给大家。各位同学如果觉得文章还不错 ,麻烦给关注和star,小弟在这里谢过啦