在上一篇博客Android本地数据存储: Reservoir 博客中,我提到,除了Reservoir库,还可以采用ASimpleCache开源库,来实现本地数据存储。昨天并没有仔细的对比Reservoir和ASimpleCache有啥不同,而是直接选取了Reservoir来进行学习使用,今天休息,真好看下ASimpleCache是如何使用的,有啥特别之处。
come on with me,let's study together。
ASimpleCache 是一个为android制定的 轻量级的 开源缓存框架。轻量到只有一个java文件(由十几个类精简而来)。
普通的字符串、JsonObject、JsonArray、Bitmap、Drawable、序列化的java对象,和 byte数据。
1:轻,轻到只有一个JAVA文件。
2:可配置,可以配置缓存路径,缓存大小,缓存数量等。
3:可以设置缓存超时时间,缓存超时自动失效,并被删除。
4:支持多进程。
1、替换SharePreference当做配置文件
2、可以缓存网络请求数据,比如oschina的android客户端可以缓存http请求的新闻内容,缓存时间假设为1个小时,超时后自动失效,让客户端重新请求新的数据,减少客户端流量,同时减少服务器并发量。
由上述介绍,我们可以得知,其实ASimpleCache就只有一个类文件,所以在使用时,我们仅需要把这个文件拷贝到我们的项目中,作为工具类即可。
那,接下来,看下如何使用ASimpleCache去存取数据吧。
ASimpleCache在使用前也必须进行初始化操作。
ACache mCache = ACache.get(this);
首先,我们看下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 }
I/System.out﹕ null
果然有效啊,是不是很惊喜啊,没错,使用这个方法之后,我们可以很方便的处理一些需求,比如本地的token过期需要重新登录(我最近刚刚做了这么一个功能需求)。。。。
仔细看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 <T> String t2Json2(T t) { return getGson().toJson(t); } /** * 将字符转化为对象 * * @param <T> * @param jsonString * @param clazz * @return */ public static <T> T json2T(String jsonString, Class<T> clazz) { return getGson().fromJson(jsonString, clazz); } /** * 将字符串数组转化为对象集合 * * @param <T> * @param jsonStr * @param type * @return */ public static <T> List<T> 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<Person> persons = new ArrayList<Person>(); 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}]
private void readDatas() { JSONArray result = mCache.getAsJSONArray(PERSONS); Type mType = new TypeToken<List<Person>>(){}.getType(); List<Person> 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方法哦,这个请大家自己去研究了。。。
和Reservoir一样,既然可以存取数据,当然也可以删除和清空缓存数据了。ACache也提供了remove和clear两个方法,分别用来删除指定key的缓存和清空所有缓存。
private void deleteData() { mCache.remove(PERSON); } private void clearData() { mCache.clear(); }
为啥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"); } }
ASimpleCache gitub地址:https://github.com/yangfuhai/ASimpleCache
上述示例源码下载地址(免费): http://download.csdn.net/detail/zuiwuyuan/9037833