前言
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,就不能给他封装了嘛~~
一看就不是自己人,用它给我干活不放心啊,给他包装下~
思路与实现
-
SharedPreferences
先看下SharedPreferences, 他本身就是interface,一看就是采用的面向接口编程,好像在告诉我,我是干这个的,你别管我咋干的,你需要用就是了~ -
定义执行部分
- 自己定义方法,创建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(); } ··· }
- 好像可以了
- 理想使用效果
- 首先是缓存分模块,比如用户信息缓存、设置配置缓存等等
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类好呢?
- 业务功能和公用功能分离
- 正常使用执行类,还需要引入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; } ··· }
- 这样继承父类后,覆盖该方法即可,如果是多人协同使用,既能看懂,又能约束
- 执行和使用结合
- 继承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(); } ···
-
缓存管理类
大功告成?还差一步!通过管理类实现缓存类的管理,并在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)); } }
使用效果
-
在Application类中初始化
PreferenceManager.getInstance().initPreferences(this);
-
正常使用
舒坦~~IUserPreferences userPreferences = PreferenceManager.getInstance().getUserPreferences(); //保存 userPreferences.saveUserName("Kyne"); //获取 String name = userPreferences.getUserName();
类图
忘了咋画了 O——O~!
网友评论