[关闭]
@asce1885 2015-08-12T08:29:41.000000Z 字数 7009 阅读 560

JSON解析函数库HFJson

新框架文档


Modified from LoganSquare
@author ASCE1885的 Github 简书 微博 CSDN

基础知识

HFJson是在著名的jackson-core解析器基础上封装的快速解析json的函数库,它使用编译时注解代替运行时注解,从而获得速度上的提升。

HFJson包括三个Module:hfjson,hfjson-example和hfjson-processor,processor是用于编译时将注解转换成java类的,已经将修改后的代码通过Gradle发布到jcenter上面,调用者只需在build.gradle中加入一行代码就可以,processor不会出现在最终的SDK和APK中。

hfjson-processor

hfjson-processor是一个Java Library,最终生成一个jar包,为了让Android Studio通过android-apt引用它,需要将这个jar包通过Gradle发布到公共仓库JCenter上。JCenter现在是Android Studio中repositories的默认节点(之前是Maven的,不过JCenter是兼容Maven的)。

申请Bintray账号

Bintray的基本功能类似于Maven Central,首先我们需要注册一个Bintray账号

配置build文件

我们需要生成项目的JavaDoc和source JARs,这两项都是要上传到JCenter的文件,由于生成过程需要用到android-maven-plugin插件,上传到bintray上面需要gradle-bintray-plugin的支持,所以在工程的build.gradle(最外层的build.gradle文件)中添加依赖如下所示:

  1. // Top-level build file where you can add configuration options common to all sub-projects/modules.
  2. buildscript {
  3. repositories {
  4. jcenter()
  5. }
  6. dependencies {
  7. classpath 'com.android.tools.build:gradle:1.1.0'
  8. classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0'
  9. classpath 'com.github.dcendents:android-maven-plugin:1.2'
  10. // NOTE: Do not place your application dependencies here; they belong
  11. // in the individual module build.gradle files
  12. }
  13. }
  14. allprojects {
  15. repositories {
  16. jcenter()
  17. }
  18. }

接着配置hfjson-processor这个module的build.gradle文件如下:

  1. apply plugin: 'java'
  2. apply plugin: 'com.github.dcendents.android-maven'
  3. apply plugin: 'com.jfrog.bintray'
  4. repositories {
  5. jcenter()
  6. }
  7. // This is the library version used when deploying the artifact
  8. version = "1.0.3"
  9. dependencies {
  10. compile fileTree(dir: 'libs', include: ['*.jar'])
  11. compile 'org.apache.commons:commons-lang3:3.2'
  12. }
  13. def siteUrl = 'https://github.com/ASCE1885/hfjson-compiler' // 项目的主页
  14. def gitUrl = 'https://github.com/ASCE1885/hfjson-compiler.git' // Git仓库的url
  15. group = "com.paic.hyperion.core.hfjson.compiler"
  16. install {
  17. repositories.mavenInstaller {
  18. // This generates POM.xml with proper parameters
  19. pom {
  20. project {
  21. packaging 'jar'
  22. // Add your description here
  23. name 'com.paic.hyperion.core.hfjson.compiler' //项目描述
  24. url siteUrl
  25. // Set your license
  26. licenses {
  27. license {
  28. name 'The Apache Software License, Version 2.0'
  29. url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
  30. }
  31. }
  32. developers {
  33. developer {
  34. id 'paichyperion' //填写的一
  35. // 些基本信息
  36. name 'hfjson-processor'
  37. email 'paichyperion@gmail.com'
  38. }
  39. }
  40. scm {
  41. connection gitUrl
  42. developerConnection gitUrl
  43. url siteUrl
  44. }
  45. }
  46. }
  47. }
  48. }
  49. task sourcesJar(type: Jar) {
  50. from sourceSets.main.java.srcDirs
  51. classifier = 'sources'
  52. }
  53. //task javadoc(type: Javadoc) {
  54. // source = sourceSets.main.java.srcDirs
  55. // // classpath += project.files(getBootClasspath().join(File.pathSeparator))
  56. //}
  57. task javadocJar(type: Jar, dependsOn: javadoc) {
  58. classifier = 'javadoc'
  59. from javadoc.destinationDir
  60. }
  61. artifacts {
  62. archives javadocJar
  63. archives sourcesJar
  64. }
  65. Properties properties = new Properties()
  66. properties.load(project.rootProject.file('local.properties').newDataInputStream())
  67. bintray {
  68. user = properties.getProperty("bintray.user")
  69. key = properties.getProperty("bintray.apikey")
  70. configurations = ['archives']
  71. pkg {
  72. repo = "maven"
  73. name = "hfjson-processor" //发布到JCenter上的项目名字
  74. websiteUrl = siteUrl
  75. vcsUrl = gitUrl
  76. licenses = ["Apache-2.0"]
  77. publish = true
  78. }
  79. }

上面文件中用到的bintray.user和bintray.apikey分别是你注册bintray的用户名,以及它生成的apikey,登录bintray点击进入你的账户信息里再点击Edit即有查看API Key的选项信息。我们把这两个值定义在工程的local.properties文件中(一般这文件需gitignore,防止泄露账户信息):

  1. bintray.user=your_user_name
  2. bintray.apikey=your_apikey

生成文件并上传到Bintray

build一下工程,并在Android Studio的Terminal窗口中cd到工程根目录,执行

  1. ./gradlew bintrayUpload

命令,即可在hfjson-compiler Module的build/libs目录中生成项目需要的jar包:

hfjson

上传完成后,即可登录Bintray网站找到hfjson-compiler这个repo,最后一步就是申请把这个repo添加到JCenter中。我们可以进入这个搜索页面检索我们的hfjson-compiler,找到后点击进入项目主页,然后找到link to选项,添加我们的package到jcenter即可,后面等待管理员审核通过就可以使用了,使用的方式是在调用者的build.gradle文件中添加如下一行依赖:

  1. buildscript {
  2. repositories {
  3. jcenter()
  4. }
  5. dependencies {
  6. classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
  7. }
  8. }
  9. apply plugin: 'com.neenbedankt.android-apt'
  10. dependencies {
  11. apt 'com.paic.hyperion.core.hfjson.compiler:hfjson-processor:1.0.3'
  12. }

API使用方法

Model类的创建

创建Model类有三种方式,下面分别进行介绍:

1. 为Model类的每个变量添加注解

  1. @HFJsonObject
  2. public class Image {
  3. /**
  4. * 标准的变量标记,表示name变量将参与到json解析和序列化中
  5. */
  6. @HFJsonField
  7. public String name;
  8. /**
  9. * 标准的变量标记,表示imageId变量参与到json解析和序列化中,而且会重命名为_id
  10. */
  11. @HFJsonField(name="_id")
  12. public int imageId;
  13. @HFJsonField
  14. public String url;
  15. /**
  16. * 虽然这是一个包访问范围的变量,但使用@HFJsonField注解后,仍然可以参与到
  17. * json的解析和序列化中
  18. */
  19. @HFJsonField(name="similar_images")
  20. List<Image> similarImages;
  21. /**
  22. * 该变量没有使用@HFJsonField注解,因此不会参与到json的解析和序列化中
  23. */
  24. public int nonJsonField;
  25. /**
  26. * 由于这是一个私有变量,因此使用@HFJsonField注解,需要同时提供该变量的
  27. * getter和setter函数,否则将会出错
  28. */
  29. @HFJsonField
  30. private int privateInt;
  31. public int getPrivateInt() {
  32. return privateInt;
  33. }
  34. public void setPrivateInt(int i) {
  35. privateInt = i;
  36. }
  37. /**
  38. * 可选的回调函数,用于该类实例结束解析后调用
  39. */
  40. @OnHFJsonParseComplete
  41. void onParseComplete() {
  42. // 在这里可以增加Json解析前的预处理
  43. }
  44. /**
  45. * 可选的回调函数,用于该类实例开始序列化之前调用
  46. */
  47. @OnPreHFJsonSerialize
  48. void onPreSerialize() {
  49. // 在这里可以增加Json序列后的后处理
  50. }
  51. }

2. 标记所有公共和包访问范围的变量

  1. /**
  2. * NONPRIVATE_FIELDS策略模式说明要标记所有非私有的变量,即使这些变量没有使用@HFJsonField注解
  3. *
  4. */
  5. @HFJsonObject(fieldDetectionPolicy = HFJsonObject.FieldDetectionPolicy.NONPRIVATE_FIELDS)
  6. public class Image2 {
  7. public String name;
  8. /**
  9. * 如果想要imageId变量在json解析和序列化中使用新的名字_id,那么还是需要单独注解
  10. */
  11. @HFJsonField(name="_id")
  12. public int imageId;
  13. public String url;
  14. /**
  15. * 包访问范围的变量仍然会参与到Json解析和序列化中
  16. */
  17. List<Image> similarImages;
  18. /**
  19. * 对于不想参与到Json解析和序列化中的变量,使用@HFJsonIgnore进行注解标记
  20. */
  21. @HFJsonIgnore
  22. public int nonJsonField;
  23. /**
  24. * 由于这是私有变量,在NONPRIVATE_FIELDS策略下,该变量将不会参与到Json解析和序列化中
  25. */
  26. private int privateInt;
  27. public int getPrivateInt() {
  28. return privateInt;
  29. }
  30. public void setPrivateInt(int i) {
  31. privateInt = i;
  32. }
  33. /**
  34. * 可选的回调函数,用于该类实例结束解析后调用
  35. */
  36. @OnHFJsonParseComplete
  37. void onParseComplete() {
  38. // 在这里可以增加Json解析前的预处理
  39. }
  40. /**
  41. * 可选的回调函数,用于该类实例开始序列化之前调用
  42. */
  43. @OnPreHFJsonSerialize
  44. void onPreSerialize() {
  45. // 在这里可以增加Json序列后的后处理
  46. }
  47. }

3. 标记所有公共和包访问范围的变量以及访问函数

  1. /**
  2. * NONPRIVATE_FIELDS_AND_ACCESSORS策略模式说明要标记所有非私有的变量以及具有getter和setter函数的私有变量,
  3. * 即使这些变量没有使用@HFJsonField注解
  4. *
  5. */
  6. @HFJsonObject(fieldDetectionPolicy = HFJsonObject.FieldDetectionPolicy.NONPRIVATE_FIELDS_AND_ACCESSORS)
  7. public class Image3 {
  8. public String name;
  9. /**
  10. * 如果想要imageId变量在json解析和序列化中使用新的名字_id,那么还是需要单独注解
  11. */
  12. @HFJsonField(name="_id")
  13. public int imageId;
  14. public String url;
  15. /**
  16. * 包访问范围的变量仍然会参与到Json解析和序列化中
  17. */
  18. List<Image> similarImages;
  19. /**
  20. * 对于不想参与到Json解析和序列化中的变量,使用@HFJsonIgnore进行注解标记
  21. */
  22. @HFJsonIgnore
  23. public int nonJsonField;
  24. /**
  25. * 由于这是私有变量,在NONPRIVATE_FIELDS_AND_ACCESSORS策略下,
  26. * 该变量如果具有setter和getter函数,那它将会参与到Json解析和序列化中
  27. * 如果两个函数缺一,或者都没有,则不参与到Json解析和序列化中
  28. */
  29. private int privateInt;
  30. public int getPrivateInt() {
  31. return privateInt;
  32. }
  33. public void setPrivateInt(int i) {
  34. privateInt = i;
  35. }
  36. /**
  37. * 可选的回调函数,用于该类实例结束解析后调用
  38. */
  39. @OnHFJsonParseComplete
  40. void onParseComplete() {
  41. // 在这里可以增加Json解析前的预处理
  42. }
  43. /**
  44. * 可选的回调函数,用于该类实例开始序列化之前调用
  45. */
  46. @OnPreHFJsonSerialize
  47. void onPreSerialize() {
  48. // 在这里可以增加Json序列后的后处理
  49. }
  50. }

Json的解析

Json解析的数据来源可以有两种:InputStream和String。

  1. // Parse from an InputStream
  2. try {
  3. InputStream is = ...;
  4. Image imageFromInputStream = HFJson.parse(is, Image.class);
  5. // Parse from a String
  6. String jsonString = ...;
  7. Image imageFromString = HFJson.parse(jsonString, Image.class);
  8. } catch (IOException e) {
  9. e.printStackTrace();
  10. }

Json的序列化

Json对象可以序列化到OutputStream和String中。

  1. try {
  2. Image image = new Image();
  3. // Serialize it to an OutputStream
  4. OutputStream os = ...;
  5. HFJson.serialize(image, os);
  6. // Serialize it to a String
  7. String jsonString = HFJson.serialize(image);
  8. } catch (IOException e) {
  9. e.printStackTrace();
  10. }

支持的数据类型

支持的内建数据类型

支持的集合类型

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注