简单快速的对象存储库:Paper(一)

QuibblerQuibbler 2022-01-05 约 8 分钟 1811 次阅读

简单快速的对象存储库:Paper(一)

在GitHub上淘宝,最近又发现一个设计精巧而简单快速的存储库:Paper,可以考虑用来替代Preference。另一位牛人César Ferreira基于Paper,结合RxJava写了一个RxPaper2。

GitHub:https://github.com/pilgr/Paper

1、Paper

Paper,正如其名:此库旨在让开发者存储对象数据,犹如在纸上写字一样轻而易举。

1.1、简介

“Paper 的目标是为 Android 提供一个简单而快速的对象存储选项。 它允许按原样使用 Java/Kotlin 类:没有注释、工厂方法、强制类扩展等。此外,向数据类添加或删除字段不再是一件痛苦的事——所有数据结构更改都将自动处理。”

在性能,易用性各方面都要相比同类型的库要强。

1.2、引入Paper库

项目中引入Paper库,只需在模块的build.gradle中加上:

dependencies {
        ...
        //https://github.com/pilgr/Paper
        implementation 'io.github.pilgr:paperdb:2.7.2'
    }

2、Paper快速上手

Paper库本身的源码很少,得益于其简洁的设计,使用非常起来很方便。有一点要注意,除了初始化操作可以放在UI线程,其它所有操作(插入、查询等等)都要放在子线程中,因为都涉及到对文件的读写操作。不过不用担心,所有的操作都是线程安全的,对同一个键的读写可以并行。

2.1、初始化

在重写应用Application的onCreate()方法中初始化Paper库:

@Override
    public void onCreate() {
        super.onCreate();
        //初始化Paper
        Paper.init(this);
    }

先看一下这里的源码,非常轻量的操作:只是初始化一下内部的Context对象将其赋值为全局Application,后面获取应用的文件目录时会用到。

/**
     * Lightweight method to init Paper instance. Should be executed in {@link Application#onCreate()}
     * or {@link android.app.Activity#onCreate(Bundle)}.
     *
     * @param context context, used to get application context
     */
    public static void init(@NonNull Context context) {
        mContext = context.getApplicationContext();
    }

2.2、插入 write

插入一条数据非常简单,两个参数:String类型的键,任意类型的值。不过值也不要太随意:如Activity这样的重对象,或者含有循环引用的对象实测无法存储。

可以指定“书”名name(目录名)和“书”放置的位置position(目录路径)。向此“书”中写入几个键值,再次写入就是更新键对应的值。对于保存的类对象,当类内部新增或删除字段时,Paper能够自动兼容,但如果字段类型发生改变就没办法了。

//默认位置,指定Book名称
    Paper.book("cn.quibbler").write("number", 10058);
    
    //指定位置,默认Book名称
    Paper.bookOn(Environment.getExternalStorageDirectory().getPath()).write("name", "Quibbler");
    
    //指定保存位置和Book名称
    Paper.bookOn("/sdcard/file/info", "cn.quibbler").write("info", new Info());

若不指定“书”名,默认“书”名是io.paperdb,这也是内部保留名称。

Paper.book().write("number", 10058);
    
    Paper.book().write("name", "Quibbler");
    
    Paper.book().write("info", new Info());

其实此“书”名就是保存键值文件的文件夹目录名,还可以指定目录的存储位置,后面看源码就会明白。

2.3、查询 read

使用read(String key)根据key查找Book中的值:

Integer number = Paper.book().read("number");
    
    //查找键值
    String name = Paper.book().read("name");
    
    //从"cn.quibbler"书中查找键所对应的值
    Info info = Paper.book("cn.quibbler").read("info");

如果查不到就会返回null,可以提供一个默认值,在没有对应值的时候返回默认值:

//查找number对应的值,若不存在返回-1    
    Integer number = Paper.book().read("number", -1);
    
    //查找name键对应的值,若没有返回default
    String name = Paper.book().read("name", "defalut");

使用Book的getAllKeys()方法返回此“书”中保存的所有键的集合:

//查询默认Book中存储的全部键值
    List<String> keys = Paper.book().getAllKeys();
    
    //查询"cn.quibbler"中的全部键值,其实也就是此目录下的全部文件名
    List<String> keys = Paper.book("cn.quibbler").getAllKeys();

使用contains(String key)方法查询是否存储了对应键:

boolean hasInfo = Paper.book().contains("info");

2.4、删除 delete

有插入就有删除,使用Book的delete(String key)方法删除键值:

Paper.book().delete("name");
    
    Paper.book("cn.quibbler").delete("info");

3、Paper原理

这里先简单了解一下它的设计思路:对于每个Book都是一个独立的文件目录,key是该目录下的文件名(不含.pt后缀),而value则是保存在文件中序列化的内容。

看一下/data/data/应用的目录结构,不同的Book对应各不同的目录,目录下的文件就是存储在当前“书”上的键值。

Paper的源码精练(不算上引用的另一个Kryo库,只有516行),设计简单、结构清晰,代码简洁的典范。


详见简单快速的对象存储库:Paper(二)一文。

相关推荐

精选
Airbnb开源项目
开源

Airbnb开源项目

Airbnb Engineering & Data ScienceAirflow Use Apache Airflow (incubating) to author workflows as directed acyclic graphs (DAGs) of tasks12,263Airpal Web UI for PrestoDB2,502Aerosolve A machine learning

1.8k
OkHttp线程池和连接池
开源

OkHttp线程池和连接池

OkHttp线程池和连接池了解了OkHttp的网络请求流程以及拦截器实现原理,再关注OkHttp中两个重要的:OkHttp的线程池和连接池。1、OkHttp线程池在OkHttp网络请求流程一文中,我们分析了OkHttp异步和同步请求流程。请求最后都在Dispatcher中分发调度处理,最后被ExecutorService执行。1.1、DispatcherDispatcher中执行任务的执行器是ex

5.2k
优美的开源动效库:Lottie
开源

优美的开源动效库:Lottie

优美的开源动效库:Lottie1、强大的动效LottieLottie是一个适用于Android,iOS,Web和Windows的库,它可以使用Bodymovin解析以json格式导出的Adobe After Effects动画,并在移动设备和Web上原生渲染它们!GitHub:https://github.com/airbnb/lottie-androidLottie官网:http://airbn

4.3k