SharedPreferences模块封装

前言

SharedPreferences 轻量级缓存使用众所周知。但是使用极其繁琐,那么现在来封装优化一下。

目录

目录.jpg

基本原理

SharedPreferences是以XML<->Map键值对的形式保存在/data/data/包名/shared_prefs文件夹下。
注意:

  • app首次使用 SP 的时候会从磁盘读取,之后缓存在内存中。
  • 区别于其他缓存,他是每次都是重新写入,之前的xml文件会被改为备份文件,如果操作成功,备份文件就会删除。

进一步了解自行查看源码。

基本使用

     SharedPreferences sharedPreferences= getSharedPreferences("user",Context.MODE_PRIVATE);
     SharedPreferences.Editor editor = sharedPreferences.edit();
     editor.putString("username", username);             
     editor.commit();

问题定义

  • edit 获取不爽,太麻烦
  • 每次获取SharedPreferences实例还需要传入name,那我要是忘了呢?
  • put时要传入key值,这要是团队协作,使用到缓存的信息,还要去查看他的key值,不科学,要是数据多了岂不更麻烦
  • 每次都要commit,就不能给他封装了嘛~~

一看就不是自己人,用它给我干活不放心啊,给他包装下~

思路与实现

  1. SharedPreferences
    先看下SharedPreferences, 他本身就是interface,一看就是采用的面向接口编程,好像在告诉我,我是干这个的,你别管我咋干的,你需要用就是了~

  2. 定义执行部分

  • 自己定义方法,创建SharedPreferences实例,实现执行,先把edit的获取包起来, 那就创建个类,通过构造函数给他实例化
    public class BasePreference {
        private SharedPreferences sharedPreferences;
        private SharedPreferences.Editor editor;
    
        public BasePreference(Context context, String name) {
            sharedPreferences = context.getSharedPreferences(name, Activity.MODE_PRIVATE);
            editor = sharedPreferences.edit();
        }
    }
    
  • 这样获取到了edit,使用他还要实现SharedPreferences的方法,那我就自己定义个~
    public interface ISharePreferences {
    
        SharedPreferences.Editor putString(String key, String value);
    
        SharedPreferences.Editor putStringSet(String key, Set<String> values);
    
        SharedPreferences.Editor putInt(String key, int value);
    
        SharedPreferences.Editor putLong(String key, long value);
    
        SharedPreferences.Editor putFloat(String key, float value);
    
        SharedPreferences.Editor putBoolean(String key, boolean value);
    
        SharedPreferences.Editor remove(String key);
    
        SharedPreferences.Editor clear();
    
        boolean commit();
    
        void apply();
    
        String getString(String key, String defValue);
        ···
    }
    
  • 这是使用的基本方法,给BasePreference实现
    public class BasePreference implements ISharePreferences {
        private SharedPreferences sharedPreferences;
        private SharedPreferences.Editor editor;
    
        public BasePreference(Context context, String name) {
            sharedPreferences = context.getSharedPreferences(name, Activity.MODE_PRIVATE);
            editor = sharedPreferences.edit();
        }
    
        @Override
        public SharedPreferences.Editor putString(String key, String value) {
            return editor.putString(key, value);
        }
    
        @Override
        public String getString(String key, String defValue) {
            return sharedPreferences.getString(key, defValue);
        }
    
        @Override
        public SharedPreferences.Editor clear() {
            return editor.clear();
        }
    
        @Override
        public boolean commit() {
            return editor.commit();
        }
    
        ···
    }
    
    
  • 好像可以了
  1. 理想使用效果
  • 首先是缓存分模块,比如用户信息缓存、设置配置缓存等等
    public class UserPreferences {
    
        private static final String TAG ="UserPreferences";
    
        public UserPreferences(Context context) {
            
        }
    
    
  • 然后使用不能太费劲,直接看类名就知道干啥的才行,定义功能接口
    public interface IUserPreferences {
    
        String getUserName();
    
        void saveUserName(String value);
    
    }
    
    
  • 实现功能
    public class UserPreferences implements IUserPreferences {
        ···
    }
    
  • 怎么用Base类好呢?
  1. 业务功能和公用功能分离
  • 正常使用执行类,还需要引入ISharePreferences接口对象,实现包装父类。
    public interface IPreference {
    
        ISharePreferences getPreferences();
    
        void commit();
    
        void clear();
    
        void remove(String key);
    }
    
    public class DefaultPreference implements IPreference {
    
        private ISharePreferences sharePreferences;
    
        public DefaultPreference(Context context, String name){
            sharePreferences = new BasePreference(context, name);
        }
    
        @Override
        public ISharePreferences getPreferences() {
            return sharePreferences;
        }
    
        @Override
        public void commit() {
            getPreferences().commit();
        }
    
        @Override
        public void clear() {
            getPreferences().clear().commit();
        }
    }
    
  • 这样公用功能和ISharePreferences对象在父类实现,还差一点,name还要传入构造函数,下面来去掉,模块类名作为name自动传入
    public class DefaultPreference implements IPreference {
    
        private String TAG = "DefaultPreference";
        private ISharePreferences sharePreferences;
    
        public DefaultPreference(Context context){
            sharePreferences = new BasePreference(context, getPreferenceName());
        }
    
        public String getPreferenceName() {
            return TAG;
        }
    
        ···
    }
    
  • 这样继承父类后,覆盖该方法即可,如果是多人协同使用,既能看懂,又能约束
  1. 执行和使用结合
  • 继承DefaultPreference, 同时调整Key的规范
    public class UserPreferences extends DefaultPreference implements IUserPreferences {
    
        private static final String TAG ="UserPreferences";
    
        public UserPreferences(Context context) {
            super(context);
        }
    
        @Override
        public String getPreferenceName() {
            return TAG;
        }
    
        @Override
        public String getUserName() {
            return getPreferences().getString(IUserConstant.USER_NAME,null);
        }
    
        @Override
        public void saveUserPassword(String value) {
            getPreferences().putString(IUserConstant.USER_NAME,value).commit();
        }
        ···
    
  1. 缓存管理类
    大功告成?还差一步!通过管理类实现缓存类的管理,并在app启动时单例实例化,防止频繁获取缓存对象,导致内容问题。
    public class PreferenceManager extends BasePreferenceManager {
    
        private static volatile PreferenceManager instance;
        private IUserPreferences userPreferences;
    
        public static PreferenceManager getInstance() {
            if (instance == null) {
                synchronized (PreferenceManager.class) {
                    if (instance == null) {
                        instance = new PreferenceManager();
                    }
                }
            }
            return instance;
        }
    
        public IUserPreferences getUserPreferences() {
            return userPreferences;
        }
    
        private void setUserPreferences(IUserPreferences userPreferences) {
            this.userPreferences = userPreferences;
        }
    
        public void initPreferences(Context context) {
            PreferenceManager.getInstance().setUserPreferences(new UserPreferences(context));
        }
    }
    

使用效果

  1. 在Application类中初始化
    PreferenceManager.getInstance().initPreferences(this);
    
  2. 正常使用
    IUserPreferences userPreferences = PreferenceManager.getInstance().getUserPreferences();
    //保存
    userPreferences.saveUserName("Kyne");
    //获取
    String name = userPreferences.getUserName();
    
    
    舒坦~~

类图

忘了咋画了 O——O~!

代码

代码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容