美文网首页
iOS Android flutter 轻量级数据缓存对比

iOS Android flutter 轻量级数据缓存对比

作者: xq9527 | 来源:发表于2021-02-15 18:54 被阅读0次

    前言

    各位同学大家好 有段时间没有给大家更新文章了, 具体多久我也记不清楚了哈 。 今天是大年初四 ,还在休假中。最近在学习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);
    
    • 效果


      image.png

      其他类型数据大家可以参考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:该模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件;
    
    1. Activity 类中的 getPreferences()方法:
       这个方法和 Context 中的 getSharedPreferences()方法很相似,不过它只接收一个操作模式参数,因为使用这个方法时会自动将当前活动的类名作为 SharedPreferences 的文件名。
    2. 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);
    
    image.png
    • 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 
    
    image.png

    在项目里面的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 本身是不支持我们要怎么做


    image.png
    image.png

    如上图是我们需要把用户名和密码起来保存 我们用传统 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,小弟在这里谢过啦

    相关文章

      网友评论

          本文标题:iOS Android flutter 轻量级数据缓存对比

          本文链接:https://www.haomeiwen.com/subject/qgnpxltx.html