一:前言
在上一篇博客Android本地数据存储: Reservoir 博客中,我提到,除了Reservoir库,还可以采用ASimpleCache开源库,来实现本地数据存储。昨天并没有仔细的对比Reservoir和ASimpleCache有啥不同,而是直接选取了Reservoir来进行学习使用,今天休息,真好看下ASimpleCache是如何使用的,有啥特别之处。
come on with me,let's study together。
二:认知ASimpleCache
ASimpleCache 是一个为android制定的 轻量级的 开源缓存框架。轻量到只有一个java文件(由十几个类精简而来)。
2.1 它可以缓存什么东西?
普通的字符串、JsonObject、JsonArray、Bitmap、Drawable、序列化的java对象,和 byte数据。
2.2 它有什么特色?
1:轻,轻到只有一个JAVA文件。
2:可配置,可以配置缓存路径,缓存大小,缓存数量等。
3:可以设置缓存超时时间,缓存超时自动失效,并被删除。
4:支持多进程。
2.3 它在android中可以用在哪些场景?
1、替换SharePreference当做配置文件
2、可以缓存网络请求数据,比如oschina的android客户端可以缓存http请求的新闻内容,缓存时间假设为1个小时,超时后自动失效,让客户端重新请求新的数据,减少客户端流量,同时减少服务器并发量。
三:使用ASimpleCache
由上述介绍,我们可以得知,其实ASimpleCache就只有一个类文件,所以在使用时,我们仅需要把这个文件拷贝到我们的项目中,作为工具类即可。
那,接下来,看下如何使用ASimpleCache去存取数据吧。
3.1 初始化ASimpleCache
ASimpleCache在使用前也必须进行初始化操作。
ACache mCache = ACache.get(this);
3.2 通过put、get方法,存取Object数据
首先,我们看下ACache提供了哪些put方法,可以用来存储什么样的数据:
可以看出来,通过put方法,可以存储普通的字符串、JsonObject、JsonArray、Bitmap、Drawable、序列化的java对象,和 byte数据,这和之前我们介绍的一样。 再仔细看下这些方法,其中有些方法,提供了一个int saveTime参数,该参数主要表明该缓存可以保存的时间。
首先,我们保存序列化对象的方法代码:
先定义一个序列化的Person类:
public class Person implements Serializable{
public String name;
public int age;
public Date birthday;
public boolean sex;
public Person(String name, int age, Date birthday, boolean sex) {
this.name = name;
this.age = age;
this.birthday = birthday;
this.sex = sex;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", birthday=" + birthday +
", sex=" + sex +
'}';
}
}
private static final String PERSON = "ONE_PERSON";
private void saveData() {
Person person = new Person("无缘", 25, new Date(), true);
mCache.put(PERSON,person);
}
So just like this,我们已经把person对象保存到了本地磁盘文件中,现在我们找到文件,并打开它看下:
sr com.lnyp.asimplecache.Person袾说r? I ageZ sexL birthdayt Ljava/util/Date;L namet Ljava/lang/String;xp sr java.util.Datehj?KYt xpw OX臈'xt 鏃犵紭
沃日,这是个啥?
别惊慌,其实这就是序列化的Person对象啦。
我们读取它看下,在此之前,先看下ACache提供了哪些get方法吧:
从方法名和返回值就可以看出来,ACache提供了一系列的方法,可以直接读取InputStream,byte,Bitmap,Object等等。。。
我们先使用getAsObject去获取我们存储的序列化的对象:
private void readData() {
Person person = (Person) mCache.getAsObject(PERSON);
System.out.println(person);
}
看下返回结果:
System.out﹕ Person{name='无缘', age=25, birthday=Sun Aug 23 04:15:22 GMT 2015, sex=true}
来,这个时候我们做个试验,关于saveTime的,看看这个过期时间到底有木有用:
private void saveData() {
Person person = new Person("无缘", 25, new Date(), true);
mCache.put(PERSON,person, 10);//保存10秒,如果超过10秒去获取这个key,将为null
}
静候十秒,再去读取Person对象,看下输出
I/System.out﹕ null
果然有效啊,是不是很惊喜啊,没错,使用这个方法之后,我们可以很方便的处理一些需求,比如本地的token过期需要重新登录(我最近刚刚做了这么一个功能需求)。。。。
3.3 通过put、get方法,存取List集合数据
仔细看3.2中提到的put和get方法,可以发现并没有提供存取List集合的方法,这其实有些给人的感觉不是那么爽,起码我有点不自在了,要知道Reservoir可是提供了的哦。
不过别急,我们可以变向的去完成List集合的存取,咋办呢?用jsonArray啊!
说白了,就是把List转换为jsonArray,然后put保存,读取的时候,再把jsonArray转换为List就好了。这里,我们需要借助gson。
先提供一个GsonUtil工具类:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.lang.reflect.Type;
import java.util.List;
/**
* Gson工具类
*
* @author lining
*/
public class GsonUtil
{
/**
* 时间格式
*/
public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
/**
* 创建GSON
*
* @return
*/
public static Gson getGson()
{
return new GsonBuilder().serializeNulls().setDateFormat(DATE_FORMAT).create();
}
/**
* 将对象转化为字符串
*
* @param obj
* @return
*/
public String Object2Json2(Object obj)
{
return getGson().toJson(obj);
}
/**
* 将对象转化为字符串(泛型实现)
*
* @param obj
* @return
*/
public static String t2Json2(T t)
{
return getGson().toJson(t);
}
/**
* 将字符转化为对象
*
* @param
* @param jsonString
* @param clazz
* @return
*/
public static T json2T(String jsonString, Class clazz)
{
return getGson().fromJson(jsonString, clazz);
}
/**
* 将字符串数组转化为对象集合
*
* @param
* @param jsonStr
* @param type
* @return
*/
public static List json2Collection(String jsonStr, Type type)
{
return getGson().fromJson(jsonStr, type);
}
}
有了这个工具类,我们试着把List存储起来:
private void saveDatas() {
Person person1 = new Person("无缘1", 25, new Date(), true);
Person person2 = new Person("无缘2", 22, new Date(), false);
Person person3 = new Person("无缘3", 21, new Date(), true);
List persons = new ArrayList();
persons.add(person1);
persons.add(person2);
persons.add(person3);
String personArray = GsonUtil.getGson().toJson(persons);
System.out.println(personArray);
mCache.put(PERSONS, personArray);
}
在磁盘中找到该文件,打开看下:
[{"name":"无缘1","birthday":"2015-08-23 04:55:41","age":25,"sex":true},{"name":"无缘2","birthday":"2015-08-23 04:55:41","age":22,"sex":false},{"name":"无缘3","birthday":"2015-08-23 04:55:41","age":21,"sex":true}]
这就是我们保存的东东了,接下来,我们读取该jsonarray,并把它转换为Lsit:
private void readDatas() {
JSONArray result = mCache.getAsJSONArray(PERSONS);
Type mType = new TypeToken>(){}.getType();
List persons = GsonUtil.getGson().fromJson(result.toString(), mType);
for (Person person:persons){
System.out.println(person);
}
}
来,看下输出的内容:
System.out﹕ Person{name='无缘1', age=25, birthday=Sun Aug 23 04:55:41 GMT 2015, sex=true}
System.out﹕ Person{name='无缘2', age=22, birthday=Sun Aug 23 04:55:41 GMT 2015, sex=false}
System.out﹕ Person{name='无缘3', age=21, birthday=Sun Aug 23 04:55:41 GMT 2015, sex=true}
怎么样,是不是实现了哦。
当然,除了这个思路,你还可以自己去修改ACache源代码,添加putList和getAsList方法哦,这个请大家自己去研究了。。。
3.4 删除和清空缓存数据
和Reservoir一样,既然可以存取数据,当然也可以删除和清空缓存数据了。ACache也提供了remove和clear两个方法,分别用来删除指定key的缓存和清空所有缓存。
private void deleteData() {
mCache.remove(PERSON);
}
private void clearData() {
mCache.clear();
}
四:强大的ASimpleCache
为啥ASimpleCache是强大的呢,因为除了存储基本的数据外,它还提供了直接存取InputSream、Bitmap、Drawable的功能。这可是了不得的,也是Reservoir没有提供的哦。
当然,存取Bitmap等特殊数据的方法和存取Object是一样一样的,此处不便多说,可以看下官方提供的例子:
public class SaveBitmapActivity extends Activity {
private ImageView mIv_bitmap_res;
private ACache mCache;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_save_bitmap);
// 初始化控件
initView();
mCache = ACache.get(this);
}
/**
* 初始化控件
*/
private void initView() {
mIv_bitmap_res = (ImageView) findViewById(R.id.iv_bitmap_res);
}
/**
* 点击save事件
*
* @param v
*/
public void save(View v) {
Resources res = getResources();
Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.img_test);
mCache.put("testBitmap", bitmap);
}
/**
* 点击read事件
*
* @param v
*/
public void read(View v) {
Bitmap testBitmap = mCache.getAsBitmap("testBitmap");
if (testBitmap == null) {
Toast.makeText(this, "Bitmap cache is null ...", Toast.LENGTH_SHORT)
.show();
mIv_bitmap_res.setImageBitmap(null);
return;
}
mIv_bitmap_res.setImageBitmap(testBitmap);
}
/**
* 点击clear事件
*
* @param v
*/
public void clear(View v) {
mCache.remove("testBitmap");
}
}
是吧,so easy,有了ASimpleCache,再也不用担心Bitmap无处存放啦。当然了,一般情况下,缓存Bitmap等数据,我们会利用更强大的开源库,如Android-Universal-Image-Loader、Xutils等,此处只是给你提供了另一种选择方案。
ASimpleCache gitub地址:https://github.com/yangfuhai/ASimpleCache
上述示例源码下载地址(免费): http://download.csdn.net/detail/zuiwuyuan/9037833