iOS Android flutter 輕量級(jí)數(shù)據(jù)緩存對(duì)比

前言

各位同學(xué)大家好 有段時(shí)間沒(méi)有給大家更新文章了, 具體多久我也記不清楚了哈 。 今天是大年初四 ,還在休假中。最近在學(xué)習(xí)iOS 開發(fā) , 了解了iOS中的輕量級(jí)數(shù)據(jù)緩存的(之前做安卓和flutter 開發(fā)的 )所以今天趁著有時(shí)間就把IOS 端 Android端 flutter 跨端的輕量級(jí)數(shù)據(jù)緩存做一個(gè)對(duì)比分享給大家 那么廢話不多說(shuō) 我們正式開始

準(zhǔn)備工作

  • iOS

安裝xcode 這個(gè)大家可以自己去appstore 搜索下載安裝即可

  • android

安卓這邊需要安裝AS(android studio)和jdk 然后配置環(huán)境變量即可

  • flutter

需要安裝flutter的開發(fā)環(huán)境:大家可以去看看之前的教程:
1 win系統(tǒng)flutter開發(fā)環(huán)境安裝教程: http://www.itdecent.cn/p/152447bc8718
2 mac系統(tǒng)flutter開發(fā)環(huán)境安裝教程:http://www.itdecent.cn/p/bad2c35b41e3

具體實(shí)現(xiàn):

  • iOS

在iOS 中我們存儲(chǔ)輕量級(jí)數(shù)據(jù)的 例如登錄的token還有 賬號(hào)密碼等等 輕量級(jí)數(shù)據(jù)的時(shí)候我們是用到了ios提供的 NSUserDefault來(lái)存儲(chǔ)數(shù)據(jù)
NSUserDefault 的特點(diǎn)
提供了簡(jiǎn)單的key -value 存儲(chǔ)

  • 單例,存取輕量級(jí)的數(shù)據(jù)
  • 一般用于用戶偏好設(shè)置
  • 升級(jí)安裝后還可以繼續(xù)使用
  • 文件存儲(chǔ)在/Library/Preferences 下
  • 支持基本數(shù)據(jù)類型
  • 保存 Interger Float Double Bool
  • 保存NSArray NSData NSString NSDictionary
  • 復(fù)雜Model 需要轉(zhuǎn)化成NSData
    系統(tǒng)提供的方法
- (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;

具體代碼調(diào)用

  • 存數(shù)據(jù)
 NSString * str=@"abd";
    //存數(shù)據(jù)
[[NSUserDefaults  standardUserDefaults] setObject:str forKey:@"test"];
  • 取數(shù)據(jù)
NSString * test= [[NSUserDefaults standardUserDefaults]stringForKey:@"test"];
NSLog(@"test = %@", test);
  • 效果


    image.png

    其他類型數(shù)據(jù)大家可以參考api方法自己去多嘗試

android

android 中我們主要是用 Sharedpreferences 來(lái)實(shí)現(xiàn)輕量級(jí)數(shù)據(jù)的存儲(chǔ)
Sharedpreferences是Android平臺(tái)上一個(gè)輕量級(jí)的存儲(chǔ)類,用來(lái)保存應(yīng)用程序的各種配置信息,其本質(zhì)是一個(gè)以“鍵-值”對(duì)的方式保存數(shù)據(jù)的xml文件,其文件保存在/data/data//shared_prefs目錄下。在全局變量上看,其優(yōu)點(diǎn)是不會(huì)產(chǎn)生Application 、 靜態(tài)變量的OOM(out of memory)和空指針問(wèn)題,其缺點(diǎn)是效率沒(méi)有上面的兩種方法高。

具體使用

  • 1.獲取SharedPreferences

要想使用 SharedPreferences 來(lái)存儲(chǔ)數(shù)據(jù),首先需要獲取到 SharedPreferences 對(duì)象。Android中主要提供了三種方法用于得到 SharedPreferences 對(duì)象。
?1. Context 類中的 getSharedPreferences()方法:
?此方法接收兩個(gè)參數(shù),第一個(gè)參數(shù)用于指定 SharedPreferences 文件的名稱,如果指定的文件不存在則會(huì)創(chuàng)建一個(gè),第二個(gè)參數(shù)用于指定操作模式,主要有以下幾種模式可以選擇。MODE_PRIVATE 是默認(rèn)的操作模式,和直接傳入 0 效果是相同的。
?MODE_WORLD_READABLE 和 MODE_WORLD_WRITEABLE 這兩種模式已在 Android 4.2 版本中被廢棄。

Context.MODE_PRIVATE: 指定該SharedPreferences數(shù)據(jù)只能被本應(yīng)用程序讀、寫;
Context.MODE_WORLD_READABLE:  指定該SharedPreferences數(shù)據(jù)能被其他應(yīng)用程序讀,但不能寫;
Context.MODE_WORLD_WRITEABLE:  指定該SharedPreferences數(shù)據(jù)能被其他應(yīng)用程序讀;
Context.MODE_APPEND:該模式會(huì)檢查文件是否存在,存在就往文件追加內(nèi)容,否則就創(chuàng)建新文件;
  1. Activity 類中的 getPreferences()方法:
    ?這個(gè)方法和 Context 中的 getSharedPreferences()方法很相似,不過(guò)它只接收一個(gè)操作模式參數(shù),因?yàn)槭褂眠@個(gè)方法時(shí)會(huì)自動(dòng)將當(dāng)前活動(dòng)的類名作為 SharedPreferences 的文件名。
  2. PreferenceManager 類中的 getDefaultSharedPreferences()方法:
    ?這是一個(gè)靜態(tài)方法,它接收一個(gè) Context 參數(shù),并自動(dòng)使用當(dāng)前應(yīng)用程序的包名作為前綴來(lái)命名 SharedPreferences 文件。
  • SharedPreferences的使用

SharedPreferences對(duì)象本身只能獲取數(shù)據(jù)而不支持存儲(chǔ)和修改,存儲(chǔ)修改是通過(guò)SharedPreferences.edit()獲取的內(nèi)部接口Editor對(duì)象實(shí)現(xiàn)。使用Preference來(lái)存取數(shù)據(jù),用到了SharedPreferences接口和SharedPreferences的一個(gè)內(nèi)部接口SharedPreferences.Editor,這兩個(gè)接口在android.content包中;

SharedPreferences 存數(shù)據(jù)

  • 1調(diào)用 源碼中 ContextWrapper中的 getSharedPreferences 方法給SharedPreferences 創(chuàng)建一個(gè)實(shí)例
  //步驟1:創(chuàng)建一個(gè)SharedPreferences對(duì)象
     SharedPreferences sharedPreferences= getSharedPreferences("data",Context.MODE_PRIVATE);
image.png
  • 2 實(shí)例化SharedPreferences.Editor對(duì)象并調(diào)用Editor 對(duì)象里面方法存數(shù)據(jù)
//步驟2: 實(shí)例化SharedPreferences.Editor對(duì)象
     SharedPreferences.Editor editor = sharedPreferences.edit();
     //步驟3:將獲取過(guò)來(lái)的值放入文件
     editor.putString("name", “xuqing”);
     editor.putInt("age", 28);
     editor.putBoolean("marrid",false);
     //步驟4:提交               
     editor.commit();

SharedPreferences取數(shù)據(jù)

讀取數(shù)據(jù):
     SharedPreferences sharedPreferences= getSharedPreferences("data", Context .MODE_PRIVATE);
     String userId=sharedPreferences.getString("name","");

刪除數(shù)據(jù)(刪除指定數(shù)據(jù))

刪除指定數(shù)據(jù)
     editor.remove("name");
     editor.commit();

清空數(shù)據(jù)

清空數(shù)據(jù)
     editor.clear();
     editor.commit();

注意:如果在 Fragment 中使用SharedPreferences 時(shí),需要放在onAttach(Activity activity)里面進(jìn)行SharedPreferences的初始化,否則會(huì)報(bào)空指針 即 getActivity()會(huì)可能返回null !

editor提供的對(duì)外方法

 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 提供的方法來(lái)看 我們的SharedPreferences 輕量級(jí)緩存 能夠存儲(chǔ)的數(shù)據(jù)只支持基本數(shù)據(jù)類型 (int long float Boolean ) 和string 引用類型 并不能存一個(gè)對(duì)象 bean這種復(fù)雜的數(shù)據(jù)類型 我們要對(duì)SharedPreferences 做些簡(jiǎn)單的封裝就能滿足我們的需求 不過(guò)我們始終要清楚 SharedPreferences 只適合輕量級(jí)數(shù)據(jù) 如果數(shù)據(jù)過(guò)多不建議使用這種方式
我們對(duì) SharedPreferences 做一些簡(jiǎn)單封裝來(lái)滿足我們的各種需求

  • 存數(shù)據(jù) 取數(shù)據(jù) 刪除數(shù)據(jù)的封裝
    private static final String TAG = "SharedPreferencesUtils";
    /**
     * 保存在手機(jī)里面的文件名
     */
    private static final String FILE_NAME = "test";
    private static SharedPreferences sp;

    /**
     * 保存數(shù)據(jù)的方法,我們需要拿到保存數(shù)據(jù)的具體類型,然后根據(jù)類型調(diào)用不同的保存方法
     *
     * @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();
    }

    /**
     * 得到保存數(shù)據(jù)的方法,我們根據(jù)默認(rèn)值得到保存的數(shù)據(jù)的具體類型,然后調(diào)用相對(duì)于的方法獲取值
     *
     * @param context
     * @param key                                             關(guān)鍵字
     * @param defaultObject                                   若取回空值則返回此默認(rèn)值
     * @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.存儲(chǔ)賬本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緩存數(shù)據(jù)
    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;
    }
  • 存儲(chǔ)到SD卡(這里順帶講一下 Android 里面 Android 6.0 以后要申請(qǐng)權(quán)限再操作SD 存儲(chǔ))

    //存數(shù)據(jù)到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卡里面的數(shù)據(jù)
    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的一個(gè)工具類
 * 使用方法:
 * 調(diào)用setParam就能保存String, Integer, Boolean, Float, Long類型的參數(shù)
 * 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>
 * 同樣調(diào)用getParam就能獲取到保存在手機(jī)里面的數(shù)據(jù)
 * 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";
    /**
     * 保存在手機(jī)里面的文件名
     */
    private static final String FILE_NAME = "test";
    private static SharedPreferences sp;

    /**
     * 保存數(shù)據(jù)的方法,我們需要拿到保存數(shù)據(jù)的具體類型,然后根據(jù)類型調(diào)用不同的保存方法
     *
     * @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();
    }

    /**
     * 得到保存數(shù)據(jù)的方法,我們根據(jù)默認(rèn)值得到保存的數(shù)據(jù)的具體類型,然后調(diào)用相對(duì)于的方法獲取值
     *
     * @param context
     * @param key                                             關(guān)鍵字
     * @param defaultObject                                   若取回空值則返回此默認(rèn)值
     * @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.存儲(chǔ)賬本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緩存數(shù)據(jù)
    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;
    }

    //存數(shù)據(jù)到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卡里面的數(shù)據(jù)
    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;
    }

    /**
     * 獲得賬號(hào)數(shù)組形式的列表(字符串轉(zhuǎn)數(shù)組)
     * 通過(guò)參數(shù)確認(rèn)是否需要翻轉(zhuǎn)排序輸出
     *
     * @param context
     * @param isReverse
     * @return
     */
    public static ArrayList getSYAccountList(Context context, boolean isReverse) {
        if (!getSYAccountArray(context).equals("")) {
            String temp = getSYAccountArray(context);
            LeLanLog.d("getSYAccountList 已緩存 賬號(hào)列表 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;
        }
    }

    /**
     * 獲取賬號(hào)列表
     *
     * @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 從賬號(hào)文件中讀取賬號(hào)數(shù)組 array=" + temp);
        String arraylist = BaseUtil.decode(temp);
        return arraylist;
    }

    /**
     * 通過(guò)賬號(hào)列表獲取到詳細(xì)用戶信息
     *
     * @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 里面的輕量級(jí)數(shù)據(jù)緩存我們都講了 在原生的andriod 和iOS 里面都會(huì)有數(shù)據(jù)緩存的api Android 端用的是 Sharedpreferences 來(lái)實(shí)現(xiàn)對(duì)于輕量級(jí)數(shù)據(jù)的緩存 , IOS端 通常使用NSUserDefaults 來(lái)實(shí)現(xiàn)輕量級(jí)數(shù)據(jù)的緩存 但是在flutter 有基于Android iOS 做支持的三方插件庫(kù) shared_preferences ,其實(shí)shared_preferences 這個(gè)庫(kù)本身底層是基于(android ) Sharedpreferences 和(ios)NSUserDefaults 封裝的
我們普通開發(fā)者在上層調(diào)用API即可

shared_preferences 使用準(zhǔn)備工作

shared_preferences: ^0.5.3+4 
image.png

在項(xiàng)目里面的pubspec.yaml 添加依賴 然后在項(xiàng)目根目錄打開控制臺(tái)輸入 flutter pub get 命令回去下載相對(duì)應(yīng)的依賴

shared_preferences基本用法

存儲(chǔ)基本數(shù)據(jù)類型:
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");
              },

刪除指定數(shù)據(jù)

其中key就是你存貯的名稱,value就是你存儲(chǔ)的值

 SharedPreferences prefs = await SharedPreferences.getInstance();
  prefs.remove(key); //刪除指定鍵

清空整個(gè)緩存:

 SharedPreferences prefs = await SharedPreferences.getInstance();
 prefs.clear();//清空鍵值對(duì)

以上是Sharedpreferences 的基礎(chǔ)用法 ,但是我們發(fā)現(xiàn)沒(méi)有每次寫一大推重復(fù)代碼 這時(shí)候我們就對(duì)Sharedpreferences 進(jìn)行簡(jiǎn)單封裝是我們減少重復(fù)代碼的編寫

  /***
   *
   * 存數(shù)據(jù)
   */

  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("不能得到這種類型");
   }
 }
  /***
   * 取數(shù)據(jù)
   *
   */
     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("不能得到這種類型");
   }
 }
  /***
   * 刪除指定數(shù)據(jù)
   */
  static void    remove(String key)async{
     SharedPreferences prefs = await SharedPreferences.getInstance();
     prefs.remove(key); //刪除指定鍵
   }
  /***
   * 清空整個(gè)緩存
   */
  static void    clear()async{
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.clear(); ////清空緩存
  }

工具類具體調(diào)用 :

存儲(chǔ)數(shù)據(jù):
  onPressed: (){
                String counter  = "1";
                SharedPreferencesUtils.savePreference(context, "counter", counter);
              },
            ),
取值

直接調(diào)用并賦值給定義的變量

 onPressed: ()async{
      String  counter = await (SharedPreferencesUtils.getPreference(context, "counter", "1")) as String ;
                 print("counter  -- > "+counter);
     },

通過(guò)then方式調(diào)用

 onPressed: ()async{
                 SharedPreferencesUtils.getPreference(context, "counter", "1").then((value){
                   print("value   --->"  +value);
                 });
              },

刪除指定key的緩存數(shù)據(jù)調(diào)用:

   SharedPreferencesUtils.remove("counter");

清空整個(gè)SharedPreferences緩存:

   SharedPreferencesUtils.clear();

基本數(shù)據(jù)類型的封裝使用我們就說(shuō)完了 大家發(fā)現(xiàn)沒(méi)有有時(shí)候我們需要存一個(gè)model其實(shí)
SharedPreferences 本身是不支持我們要怎么做


image.png

image.png

如上圖是我們需要把用戶名和密碼起來(lái)保存 我們用傳統(tǒng) SharedPreferences 來(lái)做肯定不OK 當(dāng)然有同學(xué)肯定想到說(shuō)用 sqlite 本地?cái)?shù)據(jù)庫(kù)來(lái)實(shí)現(xiàn) ,sqlite 確實(shí)可以實(shí)現(xiàn) 但是本身代碼就多不夠靈活 而且我們這邊存儲(chǔ)的字段并不多 我們這邊選擇在 SharedPreferences 上面做稍微的改造就能實(shí)現(xiàn)上面的需求的

之前的實(shí)現(xiàn)方式 :
     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);
                    },

取值轉(zhuǎn)換

    onPressed: ()async{
                      SharedPreferences prefs = await SharedPreferences.getInstance();
                      getdata = await prefs.getString("data");
                     List  list= json.decode(getdata);
                    },

獲取到值以后我們要通過(guò) json.decode 將那倒json字符串轉(zhuǎn)成list然后再來(lái)取值,這是我們傳統(tǒng)的做法 代碼量其實(shí)很大 而且如果我們有很多類似的數(shù)據(jù)要存儲(chǔ)肯定做法不夠簡(jiǎn)潔 我們這里也對(duì)于之前實(shí)現(xiàn)方式簡(jiǎn)單的封裝 代碼如下


  /**
   * 存儲(chǔ)  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;
  }

具體調(diào)用:

存儲(chǔ)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");
    },

到此整個(gè) SharedPreferences庫(kù) 數(shù)據(jù)存儲(chǔ)的基礎(chǔ)用法和特別技巧我們就講完了。

最后總結(jié)

無(wú)論是原生IOS 還是原生Android系統(tǒng)都提供了 輕量級(jí)緩存數(shù)據(jù) api 方法 供我們開發(fā)者調(diào)用,無(wú)論是iOS的 NSUserDefaults 還是 Android 的Sharedpreferences 都定位住輕量級(jí)數(shù)據(jù)緩存 存儲(chǔ)的數(shù)據(jù)類型也就是基本類型 復(fù)雜的類型我們也要通過(guò)轉(zhuǎn)換才能存儲(chǔ)和取值 還有就是 Sharedpreferences 和 NSUserDefaults 這兩端的輕量級(jí)緩存 不卸載app 或者你主動(dòng)掉調(diào)用方法刪除 數(shù)據(jù)都可以保住 更新覆蓋安裝也能保住 所以是比較適合我們?nèi)粘pp 開發(fā)的一些輕量級(jí)數(shù)據(jù)存儲(chǔ) 例如用戶token 用戶偏好 賬號(hào)密碼等等 , flutter 作為后起之秀的跨平臺(tái)方案 我們使用了 shared_preferences 這個(gè)三方庫(kù) (和Android名字很像哈)就是底層使NSUserDefaults 和 Sharedpreferences 分別IOS 端和Android 端做了封裝支持 所以我們上層開發(fā)者無(wú)需擔(dān)心使用問(wèn)題 寫這期博客也是為了讓那些非原生轉(zhuǎn)flutter的同學(xué)對(duì)于 flutter里面數(shù)據(jù)存儲(chǔ)對(duì)比原生有一個(gè)更加清楚認(rèn)知。最后希望我的文章能幫助到各位解決問(wèn)題 ,以后我還會(huì)貢獻(xiàn)更多有用的代碼分享給大家。各位同學(xué)如果覺(jué)得文章還不錯(cuò) ,麻煩給關(guān)注和star,小弟在這里謝過(guò)啦

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容