Android 撸一个缓存工具类

近两周一直在忙公司的移动项目,所以没怎么有时间学习和总结写博客。谢谢一些关心我的朋友和读者。

前言

在开发过程中,我们不可避免需要缓存许许多多的数据。例如:用户登陆后的信息;用户的状态;一些浏览的历史纪录等等;这时候我们就会经常需要读写缓存。

所以今天想通过安卓一个轻量级的存储类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());
复制代码

在这里,我们通过调用事先编写的业务存取方法saveUsergetUser保存和取出对应的单个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

我是大麦,如果喜欢我的文章,请给我一颗小心心。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值