1. 1. LoganSquare简介
  2. 2. 下载安装
  3. 3. 使用
    1. 3.0.1. 将JSON对象解析为实体类
    2. 3.0.2. 实体类序列化为JSON对象
  • 4. 混淆
  • 5. License
  • 6. 注意事项
  • 安卓上解析和序列化JSON的类库不少了,比较常用的是Google出品的GSON。但是其实还有个速度超快的LoganSquare,在解析大JSON文件的时候性能比GSON好太多,但是国内资料可能有点少,有需要的人可能并不知道如何去使用和配置这个库。我在这里向大家介绍一下。
    第一次写这种教程,很多地方其实是英文文档直接翻译过来的,肯定会有写得不好的地方,欢迎关注或者吐槽。
    【开源库不停止维护期间该资料同步更新】

    LoganSquare简介

    GITHUB地址:https://github.com/bluelinelabs/LoganSquare
    LoganSquare是Android上解析和序列化JSON最快的开源库。它的快速主要得益自Jackson’s streaming API。
    Jackson的json库提供了3种API:

    • Streaming API : 性能最好(LoganSquare所基于的API)
    • Tree Model : 最灵活
    • Data Binding : 最方便

    LoganSquare依靠编译时注释处理来生成代码,结果LoganSquare实际上既兼顾了性能,也具备Data Binding的易用性。
    即是像我这样的初鸡程序猿,也只需在model对象上使用@JsonObject注释,在字段上使用@JsonField注释,就可以无脑地解放Jackson’s streaming API的潜力。

    按照作者在*2nd gen Moto X这支手机的测试来看,比GSON和Jackson Databind快了整整400%,个人觉得简直快到爆炸~

    另外LoganSquare这个跟JSON毫无关系的奇怪的命名,其实是代码作者最喜欢的城市芝加哥的一个高人气车站的名字,也是有情调到爆炸~

    下载安装

    还在使用Eclipse的同学,很遗憾,无法使用LoganSquare 。Gradle 是 LoganSquare 唯一支持的配置方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    buildscript {
    repositories {
    jcenter()
    }
    dependencies {
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
    }
    }
    apply plugin: 'com.neenbedankt.android-apt'

    dependencies {
    apt 'com.bluelinelabs:logansquare-compiler:1.1.0'
    compile 'com.bluelinelabs:logansquare:1.1.0'
    }

    除了加入了LoganSquare依赖(只有19kb,真心小)还有apt插件,apt插件是用于运行时的注解处理的。


    使用

    • ##Step1 对要转换的实体类注解
      提供了3种类型的注解方案,主要是默认的接受转换的类属性范围有些微不同。空值的属性默认忽略。

    1.全属性注解方案

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    /*
    *所有属性接受解析和序列化。
    * 作者推荐的方案,更少错误,但要打更多的注解。
    */
    @JsonObject
    public class Image {

    /*
    * 标准的属性注解
    */
    @JsonField
    public String format;

    /*
    * 解析和序列化时,该属性的key用"_id"代替"imageId"
    */
    @JsonField(name = "_id")
    public int imageId;

    @JsonField
    public String url;

    @JsonField
    public String description;

    /*
    * 注意虽然该属性只有包访问权限,但LoganSquare可毫无障碍地处理
    */
    @JsonField(name = "similar_images")
    List<Image> similarImages;

    /*
    * 不注解的属性默认被LoganSquare忽略
    */
    public int nonJsonField;

    /*
    * !!!强烈注意private权限的属性必须提供getter和setter, 不然你会后悔的
    */
    @JsonField
    private int privateInt;

    public int getPrivateInt() {
    return privateInt;
    }

    public void setPrivateInt(int i) {
    privateInt = i;
    }

    /*
    * 还贴心地提供了解析完成后和序列化前的回调接口,当然是可选的
    */
    @OnJsonParseComplete void onParseComplete() {
    // 解析完成后干点什么
    }

    @OnPreJsonSerialize void onPreSerialize() {
    //序列化前干点什么
    }

    }

    2.非private属性注解方案

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    /*非private属性都会接受解析和序列化,即使属性没有写@JsonFields注解,但要先配置 fieldDetectionPolicy
    * 这个方案比第一个方案写少点注解
    */

    @JsonObject(fieldDetectionPolicy = FieldDetectionPolicy.NONPRIVATE_FIELDS)
    public class Image {

    /*
    *普通声明的属性默认会被解析和序列化
    */

    public String format;

    /*
    *重命名key还是需要注解来指出的
    */

    @JsonField(name = "_id")
    public int imageId;

    public String url;

    public String description;

    /*
    * 包访问权限的处理是没问题的
    */

    List<Image> similarImages;

    /*
    * 用@JsonIgnore来忽略不想被解析和序列化的属性
    */

    @JsonIgnore
    public int nonJsonField;

    /*
    * 该策略下private属性默认忽略
    */

    private int privateInt;

    public int getPrivateInt() {
    return privateInt;
    }

    public void setPrivateInt(int i) {
    privateInt = i;
    }

    @OnJsonParseComplete void onParseComplete() {
    // 解析完成后干点什么
    }

    @OnPreJsonSerialize void onPreSerialize() {
    //序列化前干点什么
    }
    }

    3.非private+Accessor注解方案

    1
    2
    3
    4
    5
    /*
    * 与第2种类似,非private属性和所有有getter和setter的属性都会被解析和序列化。可以让某些private属性
    * 也接受转换;
    * 将 fieldDetectionPolicy 设置为FieldDetectionPolicy.NONPRIVATE_FIELDS_AND_ACCESSORS即可
    */

    • ##Step2 解析&序列化

      • 将JSON对象解析为实体类

        1
        2
        3
        4
        5
        6
        7
        // 支持直接从InputStream解析
        InputStream is = ...;
        Image imageFromInputStream = LoganSquare.parse(is, Image.class);

        // 从Json字符串解析
        String jsonString = ...;
        Image imageFromString = LoganSquare.parse(jsonString, Image.class);
      • 实体类序列化为JSON对象

        1
        2
        3
        4
        5
        6
        // Serialize it to an OutputStream
        OutputStream os = ...;
        LoganSquare.serialize(image, os);

        // Serialize it to a String
        String jsonString = LoganSquare.serialize(image);

    混淆

    1
    2
    3
    -keep class com.bluelinelabs.logansquare.** { *; }
    -keep @com.bluelinelabs.logansquare.annotation.JsonObject class *
    -keep class **$$JsonObjectMapper { *; }

    License

    Copyright 2015 BlueLine Labs, Inc.
    
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
    
       http://www.apache.org/licenses/LICENSE-2.0
    
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
    

    注意事项

    LoganSquare在ART模式下才能表现出高性能,在Dalvik模式下似乎跟其他类库没有太大差距。