一:前言

今天做项目,准备使用本地存储,把一些数据存在本地磁盘上,比如用户名、密码这样的。其实大家都知道,这种情况最常用的就是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

Android本地数据存储: Reservoir的更多相关文章

  1. Android本地数据存储: ASimpleCache

    一:前言 在上一篇博客Android本地数据存储: Reservoir 博客中,我提到,除了Reservoir库,还可以采用ASimpleCache开源库,来实现本地数据存储.昨天并没有仔细的对比Re ...

  2. Android本地数据存储复习

    Android本地数据存储复习 Android无论是应用层还是系统层都需要在本地保存一些数据,尤其在应用层中使用的就更为普遍,大体有这么几种:SharedPreference,file,sqlite数 ...

  3. 理解 Android 本地数据存储 API

    利用首选项.SQLite 和内部及外部内存 API 对于需要跨应用程序执行期间或生命期而维护重要信息的应用程序来说,能够在移动设备上本地存储数据是一种非常关键的功能.作为一名开发人员,您经常需要存储诸 ...

  4. Android本地数据存储之SQLite关系型数据库 ——SQLiteDatabase

    数据库的创建,获取,执行sql语句: 框架搭建:dao 思考: 1.数据库保存在哪里? 2.如何创建数据库?如何创建表? 3.如何更新数据库?如何更改表的列数据? 4.如何获取数据库? 5.如何修改数 ...

  5. [安卓安全] 01.安卓本地数据存储:Shared Preferences安全风险浅析

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  6. Android之ListView,AsyncTask,GridView,CardView,本地数据存储,SQLite数据库

    版权声明:未经博主允许不得转载 补充 补充上一节,使用ListView是用来显示列表项的,使用ListView需要两个xml文件,一个是列表布局,一个是单个列表项的布局.如我们要在要显示系统所有app ...

  7. android学习笔记45——android的数据存储和IO

    android的数据存储和IO SharedPreferences与Editor简介 SharedPreferences保存的数据主要是类似于配置信息格式的数据,因此其保存的数据主要是简单的类型的ke ...

  8. Android实现数据存储技术

    转载:Android实现数据存储技术 本文介绍Android中的5种数据存储方式. 数据存储在开发中是使用最频繁的,在这里主要介绍Android平台中实现数据存储的5种方式,分别是: 1 使用Shar ...

  9. Android中数据存储(一)

    国庆没有给国家添堵,没有勾搭妹子,乖乖的写着自己的博客..... 本文将为大家介绍Android中数据存储的五种方式,数据存储可是非常重要的知识哦. 一,文件存储数据 ①在ROM存储数据 关于在ROM ...

随机推荐

  1. setStorage、getStorage、 removeStorage 封装

    // 本地存储 setStorage(name, data){ let dataType = typeof data; // json对象 if(dataType === 'object'){ win ...

  2. HTTP请求封装Java工具类

    装载自:http://www.open-open.com/lib/view/open1384844838743.html package com.wiker; import java.io.Buffe ...

  3. 第二周<线性回归>

    可行性分析 略 sklearn.linear_model.linear_regression() 一些参数 fit_intercept 布尔型参数,表示是否计算该模型的截距 normalize 布尔型 ...

  4. iOS自动化打包上传的踩坑记

    http://www.cocoachina.com/ios/20160624/16811.html 很久以前就看了很多关于iOS自动打包ipa的文章, 看着感觉很简单, 但是因为一直没有AppleDe ...

  5. 覆盖equals时请遵守通用约定

    Object类中非final修饰的方法有equals().hashCode().toString().finalize().clone()1.equals()方法不需要被覆盖的情况:1)实例化的对象只 ...

  6. ubuntu上制作应用程序的快捷图标启动

    最近在研究Go语言,对比了几种流行的IDE,发现GoLand是使用体验最好的,没有之一.这也印证了网友们常说的那句话“JetBrain出品,必属精品”. 在ubuntu环境下使用GoLand,直接到J ...

  7. Python之常用模块1

    1.time datetime模块 #_*_coding:utf-8_*_ __author__ = 'Alex Li' import time # print(time.clock()) #返回处理 ...

  8. qt绘制渐变区域

    // 原理:通过点到线,然后叠加成区域.同理,可使用其他图形 QPainter painter(m_pWidget); QLinearGradient linearGradient(QPointF(, ...

  9. LeetCode136 Single Number, LeetCode137 Single Number II, LeetCode260 Single Number III

    136. Single Number Given an array of integers, every element appears twice except for one. Find that ...

  10. SQLServer —— 流程控制语句

    一.IF - ELSE 语法: IF(条件) BEGIN 语句1 语句2 ... END ELSE BEGIN 语句1 语句2 ... END 说明: ELSE是可选部分,如果有多条语句,才需要BEG ...