近两周一直在忙公司的移动项目,所以没怎么有时间学习和总结写博客。谢谢一些关心我的朋友和读者。
前言
在开发过程中,我们不可避免需要缓存许许多多的数据。例如:用户登陆后的信息;用户的状态;一些浏览的历史纪录等等;这时候我们就会经常需要读写缓存。
所以今天想通过安卓一个轻量级的存储类SharedPreferences和通过Gson去实现一个单例的安卓缓存工具类;这样有利于帮助我们更好的提高开发效率。
正文
目录结构介绍(可跳过):
model
这里的model存放了一个User类和Friend类,主要是用来举例利用缓存工具类直接存放对象:
User.class
public class User {
public String name;
public String password;
public List<Friend> friends;
public User(String name, String password, List<Friend> friends) {
this.name = name;
this.password = password;
this.friends = friends;
}
public User(String name, String password) {
this.name = name;
this.password = password;
}
@Override
public String toString() {
if (friends!=null && friends.size()>0){
return "UserInfo:name"+this.name+",password"+this.password+friends.toString();
}else {
return "UserInfo:name"+this.name+",password"+this.password;
}
}
}
复制代码
Friend.class
public class Friend {
private String name;
private String password;
public Friend(String name, String password) {
this.name = name;
this.password = password;
}
@Override
public String toString() {
return "FriendInfo:name"+this.name+",password"+this.password;
}
}
复制代码
Util
工具目录下面放了两个类,SharedPreferencesUtils主要通过SharedPreferences、Gson和泛型去封装一些最基本的数据存取操作,主要包括:存取boolean类型,存取int类型,存取float类型,存取String类型,存取long类型和存取Object和List类型。
SharedPreferencesUtils
public class SharedPreferencesUtils {
private SharedPreferences.Editor mEditor;
private SharedPreferences mSharedPreferences;
private final String TAG="SharedPreferencesUtils";
public SharedPreferencesUtils(Context context){
mSharedPreferences= context
.getSharedPreferences(context.getApplicationContext().getPackageName()
, Context.MODE_PRIVATE);
mEditor=mSharedPreferences.edit();
}
/**
* 存储boolean类型的数据
* @param key
* @param value
*/
public void saveBoolean(String key,boolean value){
mEditor.putBoolean(key,value).commit();
}
/**
* 获取boolean类型的数据
* @param key
* @param defValue
* @return
*/
public boolean getBoolean(String key,boolean defValue){
return mSharedPreferences.getBoolean(key,defValue);
}
/**
* 存储int类型的数据
* @param key
* @param value
*/
public void saveInt(String key,int value){
mEditor.putInt(key,value).commit();
}
/**
* 获取int类型的数据
* @param key
* @param defValue
* @return
*/
public int getInt(String key,int defValue){
return mSharedPreferences.getInt(key,defValue);
}
/**
* 存储float类型的数据
* @param key
* @param value
*/
public void saveFloat(String key,float value){
mEditor.putFloat(key,value).commit();
}
/**
* 获取float类型的数据
* @param key
* @param defValue
* @return
*/
public float getFloat(String key,float defValue){
return mSharedPreferences.getFloat(key,defValue);
}
/**
* 存储String类型的数据
* @param key
* @param value
*/
public void saveString(String key,String value){
mEditor.putString(key,value).commit();
}
/**
* 获取String类型的数据
* @param key
* @param defValue
* @return
*/
public String getString(String key,String defValue){
return mSharedPreferences.getString(key,defValue);
}
/**
* 存储long类型的数据
* @param key
* @param value
*/
public void saveLong(String key,long value){
mEditor.putLong(key,value).commit();
}
/**
* 获取long类型的数据
* @param key
* @param defValue
* @return
*/
public long getLong(String key,long defValue){
return mSharedPreferences.getLong(key,defValue);
}
/**
* 通过Gson转换成json格式的String进行存储对象
* @param key
* @param value
*/
public void saveObject(String key,Object value){
this.saveString(key,new Gson().toJson(value));
}
/**
* 通过Gson去解析json格式,转换回对象返回
* 如果为空,则返回null
* @param key
* @param classType
* @param <T>
* @return
*/
public <T> T getObject(String key,Class<T> classType){
String objectInfo=getString(key,"");
if (objectInfo!=null && !objectInfo.isEmpty()){
T result=null;
try{
result = new Gson().fromJson(objectInfo,classType);
}catch (Exception e){
Log.d(TAG,e.toString());
}
return result;
}else {
return null;
}
}
/**
* 保存对象列表
* @param key
* @param value
* @param <T>
*/
public <T> void saveList(String key,List<T> value){
saveString(key,new Gson().toJson(value));
}
/**
* 获取对象列表,如果为空,则返回null
* @param key
* @param typeToken
* @param <T>
* @return
*/
public <T> List<T> getList(String key,TypeToken<List<T>> typeToken){
String objectInfo=getString(key,"");
if (objectInfo!=null && !objectInfo.isEmpty()){
List<T> result=null;
try{
result=new Gson().fromJson(objectInfo,typeToken.getType());
}catch (Exception e){
Log.d(TAG,e.toString());
}
return result;
}else {
return null;
}
}
/**
* 清除所有缓存
*/
public void clearAll(){
mEditor.clear();
mEditor.commit();
}
}
复制代码
DataCacheUtil
这个工具类主要是通过获取SharedPreferencesUtils的实例,去封装也写业务层的存取逻辑。
public class DataCacheUtil {
private SharedPreferencesUtils mSharedPreferences;
private static DataCacheUtil mInstance;
/**
* 通过单例模式实例化对象
* @param context
*/
private DataCacheUtil(Context context){
mSharedPreferences=new SharedPreferencesUtils(context);
}
public static DataCacheUtil getInstance(Context context){
if (mInstance==null){
synchronized (DataCacheUtil.class){
if (mInstance==null){
mInstance=new DataCacheUtil(context.getApplicationContext());
}
}
}
return mInstance;
}
/**
* 保存单个用户数据存储
* @param user
*/
public void saveUser(User user){
mSharedPreferences.saveObject("user_info",user);
}
/**
* 获取单个用户数据
* @return
*/
public User getUser(){
return mSharedPreferences.getObject("user_info",User.class);
}
/**
* 保存List<User>对象
* @param users
*/
public void saveUserList(List<User> users){
mSharedPreferences.saveList("user_list_info",users);
}
/**
* 获取List<User>对象
* @return
*/
public List<User> getUserList(){
return mSharedPreferences.getList("user_list_info",new TypeToken<List<User>>(){});
}
/**
* 保存User对象,对象中包括List<Friend>列表
* @return
*/
public void saveUserWithFriend(User user){
mSharedPreferences.saveObject("user_with_friend",user);
}
/**
* 获取User对象,对象中包括List<Friend>列表
* @return
*/
public User getUserWithFriend(){
return mSharedPreferences.getObject("user_with_friend",User.class);
}
}
复制代码
以上两个类,我们会在下面的文章中详细介绍它的设计和使用。
如何使用
首先我们介绍下如何使用上面的工具类。
第一步获取DataCacheUtil单例
通过调用DataCacheUtil.getInstance(context)
获取一个DataCacheUtil的单例。
第二部调用对应的业务方法去存取数据
例如:
//存取单个User对象
User user=new User("DaMai","DaMai123456");
DataCacheUtil.getInstance(getApplicationContext()).saveUser(user);
Log.d("DaMai",DataCacheUtil.getInstance(getApplicationContext()).getUser().toString());
复制代码
在这里,我们通过调用事先编写的业务存取方法saveUser
和getUser
保存和取出对应的单个User对象。
是不是很简单???
设计思路
保存对象和对象列表
保存boolean、int、float、long、String类型的数据其实没什么好说的,SharedPreferences.Editor都已经提供了对应的api。我们只要调用对应的api即可。
这里我们重点说一下我们在SharedPreferencesUtils
中如何保存对象和对象列表。
保存对象和对象列表
这里我主要通过利用Gson,去将我们要保存的对象转换成了json格式,然后通过调用saveString
方法去保存json数据格式的字符串。
获取对象和对象列表
同样的,我们先通过getString
方法去获取到对应的json格式的对象数据,然后通过Gson的fromJson
方法去将json格式的String转换回对象或对象列表类型。
以getObject
为例:
/**
* 通过Gson去解析json格式,转换回对象返回
* 如果为空,则返回null
* @param key
* @param classType
* @param <T>
* @return
*/
public <T> T getObject(String key,Class<T> classType){
String objectInfo=getString(key,"");
if (objectInfo!=null && !objectInfo.isEmpty()){
T result=null;
try{
result = new Gson().fromJson(objectInfo,classType);
}catch (Exception e){
Log.d(TAG,e.toString());
}
return result;
}else {
return null;
}
}
复制代码
这里我们将getObject
设计成泛型方法。
第一步通过key取出json格式的字符串数据。
第二步我们通过对字符串判断是否为null或者为空字符,如果为空字符串则直接返回null。
第三步通过Gson的fromJson()
方法传入json格式的字符串和类类型,并返回泛型。
对象列表也采用了同样的设计思路,这里不在赘述。
DataCacheUtil采用单例的模式
/**
* 通过单例模式实例化对象
* @param context
*/
private DataCacheUtil(Context context){
mSharedPreferences=new SharedPreferencesUtils(context);
}
/**
* 调用构造函数时,传入context.getApplicationContext()
* @param context
* @return
*/
public static DataCacheUtil getInstance(Context context){
if (mInstance==null){
synchronized (DataCacheUtil.class){
if (mInstance==null){
mInstance=new DataCacheUtil(context.getApplicationContext()); //传入context.getApplicationContext()
}
}
}
return mInstance;
}
复制代码
由于我们DataCacheUtil可能会在应用全局各个地方都使用DataCacheUtil工具类,所以我们在运用单例的过程中调用构造函数实例化SharedPreferencesUtils时,传入的context是ApplicationContext,这样做是因为防止Activity的context由于生命周期的原因,导致内存泄漏。
Demo展示
MainActivity.class
public class MainActivity extends AppCompatActivity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//存取单个User对象
User user=new User("DaMai","DaMai123456");
DataCacheUtil.getInstance(getApplicationContext()).saveUser(user);
Log.d("DaMai",DataCacheUtil.getInstance(getApplicationContext()).getUser().name);
List<User> userList=new ArrayList<>();
for (int i=0;i<10;i++){
User temUser=new User("DaMai"+i,"DaMaiPass"+i);
userList.add(temUser);
}
DataCacheUtil.getInstance(getApplicationContext()).saveUserList(userList);
List<User> users=DataCacheUtil.getInstance(this).getUserList();
for (User item:userList){
Log.d("DaMai",item.toString());
}
List<Friend> friends=new ArrayList<>();
for (int i=0;i<10;i++){
Friend temFriend=new Friend("DaMai friend"+i,"DaMaiFriendPass"+i);
friends.add(temFriend);
}
User vicky=new User("vicky","vicky123456",friends);
DataCacheUtil.getInstance(this).saveUserWithFriend(vicky);
Log.d("DaMai",DataCacheUtil.getInstance(this).getUserWithFriend().toString());
}
}
复制代码
输出:
07-19 17:16:08.630 26628-26628/com.example.sharedpreferencesdemo D/DaMai: DaMai
07-19 17:16:08.637 26628-26628/com.example.sharedpreferencesdemo D/DaMai: UserInfo:nameDaMai0,passwordDaMaiPass0
07-19 17:16:08.637 26628-26628/com.example.sharedpreferencesdemo D/DaMai: UserInfo:nameDaMai1,passwordDaMaiPass1
07-19 17:16:08.638 26628-26628/com.example.sharedpreferencesdemo D/DaMai: UserInfo:nameDaMai2,passwordDaMaiPass2
07-19 17:16:08.638 26628-26628/com.example.sharedpreferencesdemo D/DaMai: UserInfo:nameDaMai3,passwordDaMaiPass3
07-19 17:16:08.638 26628-26628/com.example.sharedpreferencesdemo D/DaMai: UserInfo:nameDaMai4,passwordDaMaiPass4
07-19 17:16:08.638 26628-26628/com.example.sharedpreferencesdemo D/DaMai: UserInfo:nameDaMai5,passwordDaMaiPass5
07-19 17:16:08.638 26628-26628/com.example.sharedpreferencesdemo D/DaMai: UserInfo:nameDaMai6,passwordDaMaiPass6
07-19 17:16:08.638 26628-26628/com.example.sharedpreferencesdemo D/DaMai: UserInfo:nameDaMai7,passwordDaMaiPass7
07-19 17:16:08.638 26628-26628/com.example.sharedpreferencesdemo D/DaMai: UserInfo:nameDaMai8,passwordDaMaiPass8
07-19 17:16:08.638 26628-26628/com.example.sharedpreferencesdemo D/DaMai: UserInfo:nameDaMai9,passwordDaMaiPass9
07-19 17:16:08.643 26628-26628/com.example.sharedpreferencesdemo D/DaMai: UserInfo:namevicky,passwordvicky123456[FriendInfo:nameDaMai friend0,passwordDaMaiFriendPass0, FriendInfo:nameDaMai friend1,passwordDaMaiFriendPass1, FriendInfo:nameDaMai friend2,passwordDaMaiFriendPass2, FriendInfo:nameDaMai friend3,passwordDaMaiFriendPass3, FriendInfo:nameDaMai friend4,passwordDaMaiFriendPass4, FriendInfo:nameDaMai friend5,passwordDaMaiFriendPass5, FriendInfo:nameDaMai friend6,passwordDaMaiFriendPass6, FriendInfo:nameDaMai friend7,passwordDaMaiFriendPass7, FriendInfo:nameDaMai friend8,passwordDaMaiFriendPass8, FriendInfo:nameDaMai friend9,passwordDaMaiFriendPass9]
复制代码
复盘:
1、运用Gson将对象转成Json格式的字符串进行存储,并通过泛型和Gson将Json格式的数据转成对象进行取出。
2、业务工具类由于在全局中频繁使用,采用了单例模式。并在实例化的过程中运用getApplicationContext()去初始化SharedPreferences,避免因为Activity的生命周期导致的内存泄露。
Demo Git地址:
缓存工具类Git地址:https://github.com/VickyGit/DataChacheDemo
我是大麦,如果喜欢我的文章,请给我一颗小心心。