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

Quibbler 2022-1-5 699

简单快速的对象存储库: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、初始化

        在重写应用ApplicationonCreate()方法中初始化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");

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

    //查询默认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

        有插入就有删除,使用Bookdelete(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(二)一文


不忘初心的阿甘
最新回复 (0)
    • 安卓笔记本
      2
        登录 注册 QQ
返回
仅供学习交流,切勿用于商业用途。如有错误欢迎指出:fluent0418@gmail.com