Android本地数据存储: Reservoir
一:前言
今天做项目,准备使用本地存储,把一些数据存在本地磁盘上,比如用户名、密码这样的。其实大家都知道,这种情况最常用的就是SharedPreferences了,我也不例外,脑子里第一个想到的就是用这个。。。后来转念一想,有没有啥开源的轻量级的库,可以更好的帮我完成这件事呢,于是求助了度娘,果不其然,被我找到了两个库,Reservoir和ASimpleCache。
原谅我没有过多的去比较这两个库,直接采用了Reservoir,去实现本地数据存储。
啥是Reservoir呢?
官方说,Reservoir是一个简单的Android函数库,可以在磁盘上使用“键/值”对轻松地序列化并持久化对象。说白了,使用Reservoir,你可以把java对象进行序列化,并把它存储到磁盘上。当然,当你想从磁盘上查找到你保存的数据时,同样需要时用Reservoir。
二:
在Android Studio上配置Reservoir库
2.1
在project的gradle上,你需要添加
repositories
{
jcenter()
}
2.2
在你module的gradle上,你需要添加Reservoir库
dependencies
{
compile 'com.anupcowkur:reservoir:2.1'
}
三:
使用Reservoir存取数据
3.1 初始化Reservoir
Resrvoir在使用前,必须先进行初始化,一般情况下,我们会把该初始化操作方在Application的onCreate()方法里:
try {
Reservoir.init(this, 2048);
} catch (Exception e) {
e.printStackTrace();
}
初始化是必须进行的操作,假设我们未进行Reservoir的初始化,而直接使用它进行了数据的存取,则会出错:
3.2
使用Reservoir提供的put、putAsync方法进行数据存储
Reservoir提供了put、putAsync两个方法进行对象数据的存储,从名字就可以看出,一个是异步,一个是同步,本身并无多少区别,我们看下它提供了哪些存储对象的方法:
为了演示对象的存储,先提供一个Person类:
public class Person {
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 +
'}';
}
}
接下来,我们使用put方法,存储单个对象:
private static final String PERSON = "ONE_PERSON";
private void saveData() {
Person person = new Person("无缘", 25, new Date(), true);
try {
Reservoir.put(PERSON, person);
} catch (Exception e) {
e.printStackTrace();
}
}
当然,我们也可以使用putAsync
private void saveDataAsync(){
Person person = new Person("无缘", 25, new Date(), true);
Reservoir.putAsync(PERSON, person, new ReservoirPutCallback() {
@Override
public void onSuccess() {
System.out.println("success");
} @Override
public void onFailure(Exception e) {
e.printStackTrace()
}
});
}
可以看出,putAsync在方法中多了一个回调处理,可以用来处理数据是否被保存到了磁盘上。
当然,除了保存单个的对象外,Reservoir支持保存一个集合。
private static final String PERSONS = "MUCH_PERSON";
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);
try {
Reservoir.put(PERSONS, persons);
} catch (Exception e) {
e.printStackTrace();
}
}
就这么简单,我们已经把一个List集合保存到了本地磁盘中,接下来,让我们看看,这些数据是以怎样的格式存储的。打开File
Explorer/data/data/package name/cache/Reservoir
没错,就是这几个文件,把它们导出来,打开看下,你会发现:
[{"name":"无缘1","birthday":"Aug 22, 2015 2:56:38 PM","age":25,"sex":true},{"name":"无缘2","birthday":"Aug 22, 2015 2:56:38 PM","age":22,"sex":false},{"name":"无缘3","birthday":"Aug 22, 2015 2:56:38 PM","age":21,"sex":true}]
没错,就是json格式,对象被序列化后,是以json格式保存在磁盘文件中的。
3.3
使用Reservoir提供的get、getAsync方法读取数据
数据既然可以存储在磁盘上,当然可以读取啦,这是毋庸置疑的。
与Reservoir提供的put方法对应,它也提供了get方法,来读取数据。
顾名思义,Reservoir通过get及getAsync两个方法,可以读取磁盘中的文件。
让我们看看代码示例:
private void readData() {
try {
if (Reservoir.contains(PERSON)) {
System.out.println(Reservoir.get(PERSON, Person.class));
;
}
} catch (Exception e) {
e.printStackTrace();
}
}
程序输出:Person{name='无缘', age=25, birthday=Sat Aug 22 15:09:16 GMT 2015, sex=true}
接下来,仔细看下上述代码,注释的部分,你会发现,我们先进行了一步判断,这是必须要进行的一步,因为如果你不进行判断的话,可能会出现key不存在情况,继而会引发空指向异常
是吧,这更说明了上述进行contains key判断的必要性。
当然,我们还可以取出集合数据:
private void readDatas() {
try {
if (Reservoir.contains(PERSONS)) {
List persons = Reservoir.get(PERSONS, List.class);
for (int i = 0; i < persons.size(); i++) {
System.out.println(persons.get(i));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
有个地方需要注意的是,我们取出集合数据是,是直接把它赋值给List,而不是List<Person>,这说明了,取出来的数据,已经失去了泛型(即泛型擦除)。不信么,那你看看:
private void readDatas() {
try {
if (Reservoir.contains(PERSONS)) {
List<Person> persons = Reservoir.get(PERSONS, List.class);
// for (int i = 0; i < persons.size(); i++) {
// System.out.println(persons.get(i));
// }
for (Person person : persons) {
System.out.println(person);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
运行:
很明显,类型转换异常,我们无法把List强转为Person,那如果我需要List<Person>集合该怎么办呢?好办,使用Type呗:
private void readDatas() {
try {
if (Reservoir.contains(PERSONS)) {
Type resultType = new TypeToken<List<Person>>() {
}.getType();
try {
List<Person> persons = Reservoir.get(PERSONS, resultType);
for (Person person : persons) {
System.out.println(person);
}
} catch (Exception e) {
//failure
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
再运行,看输出:
08-22 15:22:27.077 32747-32747/com.lnyp.reservoir I/System.out﹕ Person{name='无缘1', age=25, birthday=Sat Aug 22 15:18:56 GMT 2015, sex=true}
08-22 15:22:27.077 32747-32747/com.lnyp.reservoir I/System.out﹕ Person{name='无缘2', age=22, birthday=Sat Aug 22 15:18:56 GMT 2015, sex=false}
08-22 15:22:27.077 32747-32747/com.lnyp.reservoir I/System.out﹕ Person{name='无缘3', age=21, birthday=Sat Aug 22 15:18:56 GMT 2015, sex=true}
3.4 使用Reservoir提供的delete、clear方法删除和情况缓存数据
当我们需要删除,或者是直接清空本地磁盘缓存时,Reservoir也给提供了非常简单的方法:
3.4.1 删除key值为PERSON的数据缓存:
private void deleteData() {
try {
if (Reservoir.contains(PERSON)) {
Reservoir.delete(PERSON);
}
} catch (Exception e) {
e.printStackTrace();
}
}
3.4.2 清空本地所有的缓存:
private void clearData() {
try {
Reservoir.clear();
} catch (Exception e) {
e.printStackTrace();
}
}
就是这么简单,就是这么任性,简单,好使,这就是Reservoir。
四: 总结
通过上文的介绍,大家该知道Reservoir是多么的好用了吧,没错,简单好使,这是它给我最直接的印象。更多的介绍,可以去看下Reservoir
的源代码。
Reservoir gitub地址:https://github.com/anupcowkur/Reservoir
上述示例源码下载地址:http://download.csdn.net/detail/zuiwuyuan/9036747
最新文章
- zabbix3.0.4 邮件告警详细配置
- GitBook制作电子书详细教程(命令行版)
- SpringMVC入门配置和简单实现
- JDBC数据库编程基本流程
- [HIHO1322]树结构判定(并查集)
- java Map及Map.Entry详解(转)
- PC-大概最全的黑客工具表了
- runnable和thread的区别
- 【酷Q插件制作】教大家做一个简单的签到插件
- WM_PAINT在微软官方定义中,wParam和lParam都没有使用,所以就被Delphi给重定义了这个消息,还增加了DC(Delphi可任意改写消息的结构)
- ABP领域层——领域事件(Domain events)
- sqlserver 注释提取工具
- Kafka入门介绍
- 5种做法实现table表格中的斜线表头效果
- Linux下安装Python3.x和第三方库
- ECMA Script 6_对象的扩展
- Linux命令(十二)制作静态库和共享库
- AWK常用技巧
- 贪心Crossing river
- C#winform菜单权限分配,与菜单同步的treeView树状菜单权限控制使用心得
热门文章
- Leetcode622.Design Circular Queue设计循环队列
- bzoj 2705 [SDOI2012]Longge的问题——欧拉函数大水题
- vue渲染学生信息
- 项目ITP(七) javaWeb 整合 Quartz 实现动态调度 而且 持久化
- 前端框架中 “类mixin” 模式的思考
- 备考2019年6月份PMP考试-分享一些考试笔记(二)
- 【51NOD1304】字符串的相似度
- nodeJs学习-16 数据字典示例
- hadoop生态系统默认port集合
- 启动Jmeter录制代理进行录制,报 jmeter.protocol.http.proxy.ProxyControl