用scala开发android,用spray-json解析json

最近正在用纯Scala来写android 的APP,踩了不少的坑,为了解析个json都折腾了半天,之前打算用gson,fastJson的没成功,后来用了spray-json,下面总结一下

环境搭建

最顶层的build.gradle文件中添加scala插件的依赖路径和地址,如下所示

buildscript {
    repositories {
        jcenter()
        maven { url 'https://jitpack.io' }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'
        classpath 'com.github.xingda920813:gradle-android-scala-plugin:android-gradle-2.3.0'
    }
}

allprojects {
    repositories {
        jcenter()
        mavenCentral()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

在Applicaiton项目的build.gradle中增加apply plugin: "jp.leafytree.android-scala",在dependencies 中添加scala库和spray-json库

   apply plugin: 'com.android.application'
   apply plugin: "jp.leafytree.android-scala"

dependencies {
   ...
    compile 'org.scala-lang:scala-library:2.11.8'
    compile 'io.spray:spray-json_2.11:1.3.3'
   ...
}

scala-library:2.11.8表示用的是scala的2.11.8版本,而io.spray:spray-json_2.11:1.3.3中的2.11表示spray-json兼容scala的2.11.x版本,scala的一大坑人之处就是不同版本之间兼容做的不太好,总是报许多莫名其妙的错误,因此在选用scala的第三库的时候要特别留心它所兼容的scala版本号。

上面的环境搭建好了以后,照着spray-json的说明文档编译的时候还是出了不少的错,后来鬼使神差地修改了一下scala编译器的配置选项,竟然OK了,可能是因为我电脑上只能装的jdk是1.8的缘故。

jvm版本设置

另外我电脑上也安装了Scala的开发环境,不知道不安装对编译程序有没有影响,我电脑上安装的scala版本是2.12.2,至于如何安装scala,最好还是参考scala的官网
检查scala是否安装成功

解析数据

现以豆瓣网上电影Top250数据为例子,相关Api参见此处,因为限于篇幅,只是列出了前两部电影,其格式如下:

{
    "count": 20,
    "start": 0,
    "total": 250,
    "title": "豆瓣电影Top250",
    "subjects": [
     {
            "rating": {
                "max": 10,
                "average": 9.6,
                "stars": "50",
                "min": 0
            },
            "genres": [
                "犯罪",
                "剧情"
            ],
            "title": "肖申克的救赎",
            "casts": [
                {
                    "alt": "https://movie.douban.com/celebrity/1054521/",
                    "avatars": {
                        "small": "https://img3.doubanio.com/img/celebrity/small/17525.jpg",
                        "large": "https://img3.doubanio.com/img/celebrity/large/17525.jpg",
                        "medium": "https://img3.doubanio.com/img/celebrity/medium/17525.jpg"
                    },
                    "name": "蒂姆·罗宾斯",
                    "id": "1054521"
                },
                {
                    "alt": "https://movie.douban.com/celebrity/1054534/",
                    "avatars": {
                        "small": "https://img3.doubanio.com/img/celebrity/small/34642.jpg",
                        "large": "https://img3.doubanio.com/img/celebrity/large/34642.jpg",
                        "medium": "https://img3.doubanio.com/img/celebrity/medium/34642.jpg"
                    },
                    "name": "摩根·弗里曼",
                    "id": "1054534"
                },
                {
                    "alt": "https://movie.douban.com/celebrity/1041179/",
                    "avatars": {
                        "small": "https://img1.doubanio.com/img/celebrity/small/5837.jpg",
                        "large": "https://img1.doubanio.com/img/celebrity/large/5837.jpg",
                        "medium": "https://img1.doubanio.com/img/celebrity/medium/5837.jpg"
                    },
                    "name": "鲍勃·冈顿",
                    "id": "1041179"
                }
            ],
            "collect_count": 1135009,
            "original_title": "The Shawshank Redemption",
            "subtype": "movie",
            "directors": [
                {
                    "alt": "https://movie.douban.com/celebrity/1047973/",
                    "avatars": {
                        "small": "https://img3.doubanio.com/img/celebrity/small/230.jpg",
                        "large": "https://img3.doubanio.com/img/celebrity/large/230.jpg",
                        "medium": "https://img3.doubanio.com/img/celebrity/medium/230.jpg"
                    },
                    "name": "弗兰克·德拉邦特",
                    "id": "1047973"
                }
            ],
            "year": "1994",
            "images": {
                "small": "https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p480747492.webp",
                "large": "https://img3.doubanio.com/view/movie_poster_cover/lpst/public/p480747492.webp",
                "medium": "https://img3.doubanio.com/view/movie_poster_cover/spst/public/p480747492.webp"
            },
            "alt": "https://movie.douban.com/subject/1292052/",
            "id": "1292052"
        },
        {
            "rating": {
                "max": 10,
                "average": 9.5,
                "stars": "50",
                "min": 0
            },
            "genres": [
                "剧情",
                "爱情",
                "同性"
            ],
            "title": "霸王别姬",
            "casts": [
                {
                    "alt": "https://movie.douban.com/celebrity/1003494/",
                    "avatars": {
                        "small": "https://img1.doubanio.com/img/celebrity/small/67.jpg",
                        "large": "https://img1.doubanio.com/img/celebrity/large/67.jpg",
                        "medium": "https://img1.doubanio.com/img/celebrity/medium/67.jpg"
                    },
                    "name": "张国荣",
                    "id": "1003494"
                },
                {
                    "alt": "https://movie.douban.com/celebrity/1050265/",
                    "avatars": {
                        "small": "https://img3.doubanio.com/img/celebrity/small/46345.jpg",
                        "large": "https://img3.doubanio.com/img/celebrity/large/46345.jpg",
                        "medium": "https://img3.doubanio.com/img/celebrity/medium/46345.jpg"
                    },
                    "name": "张丰毅",
                    "id": "1050265"
                },
                {
                    "alt": "https://movie.douban.com/celebrity/1035641/",
                    "avatars": {
                        "small": "https://img1.doubanio.com/img/celebrity/small/1399268395.47.jpg",
                        "large": "https://img1.doubanio.com/img/celebrity/large/1399268395.47.jpg",
                        "medium": "https://img1.doubanio.com/img/celebrity/medium/1399268395.47.jpg"
                    },
                    "name": "巩俐",
                    "id": "1035641"
                }
            ],
            "collect_count": 810842,
            "original_title": "霸王别姬",
            "subtype": "movie",
            "directors": [
                {
                    "alt": "https://movie.douban.com/celebrity/1023040/",
                    "avatars": {
                        "small": "https://img3.doubanio.com/img/celebrity/small/750.jpg",
                        "large": "https://img3.doubanio.com/img/celebrity/large/750.jpg",
                        "medium": "https://img3.doubanio.com/img/celebrity/medium/750.jpg"
                    },
                    "name": "陈凯歌",
                    "id": "1023040"
                }
            ],
            "year": "1993",
            "images": {
                "small": "https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p1910813120.webp",
                "large": "https://img3.doubanio.com/view/movie_poster_cover/lpst/public/p1910813120.webp",
                "medium": "https://img3.doubanio.com/view/movie_poster_cover/spst/public/p1910813120.webp"
            },
            "alt": "https://movie.douban.com/subject/1291546/",
            "id": "1291546"
        }
    ]
}

根据上面的json定义对应的实体类,一般scalacase class,类似于java中JavaBeankotlin中的data class


  /**
    * 评分
    */
  case class Rating(max: Int, average: Float, stars: String, min: Int)

  /**
    * 图片
    */
  case class Avatars(small: String, large: String, medium: String)

  /**
    * 人(演员或者导演)
    */
  case class Person(alt: String, avatars: Avatars, name: String, id: String)

  /**
    * 电影主题
    */
  case class Subject(
                      rating: Rating,
                      genres: List[String],
                      title: String,
                      casts: List[Person],
                      collect_count: Int,
                      original_title: String,
                      subtype: String,
                      directors: List[Person],
                      year: String,
                      images: Avatars,
                      alt: String,
                      id: String
                    )

  /**
    * Top250,整体返回的json
    **/
  case class Top250(count: Int, start: Int, total: Int, subjects: List[Subject], title: String)

定义解析协议


  object ResultJsonProtocol extends DefaultJsonProtocol {
    implicit val ratingFormat = jsonFormat(Rating, "max", "average", "stars", "min")
    implicit val avatarsFormat = jsonFormat(Avatars, "small", "large", "medium")
    implicit val personFormat = jsonFormat(Person, "alt", "avatars", "name", "id")
    implicit val subjectFormat = jsonFormat(Subject, "rating", "genres", "title", "casts", "collect_count", "original_title", "subtype", "directors", "year", "images", "alt", "id")
    implicit val resultFormat = jsonFormat(Top250, "count", "start", "total", "subjects", "title")

  }

使用解析协议解析数据

   import spray.json._
    val jsonValue =
      """
        |{
        | "count": 20,
        | "start": 0,
        | "total": 250,
        |   "title": "豆瓣电影Top250",
        |   "subjects": [
        |    {
        |            "rating": {
        |                "max": 10,
        |                "average": 9.6,
        |                "stars": "50",
        |                "min": 0
        |            },
        |            "genres": [
        |                "犯罪",
        |                "剧情"
        |            ],
        |            "title": "肖申克的救赎",
        |            "casts": [
        |                {
        |                    "alt": "https://movie.douban.com/celebrity/1054521/",
        |                    "avatars": {
        |                        "small": "https://img3.doubanio.com/img/celebrity/small/17525.jpg",
        |                        "large": "https://img3.doubanio.com/img/celebrity/large/17525.jpg",
        |                        "medium": "https://img3.doubanio.com/img/celebrity/medium/17525.jpg"
        |                    },
        |                    "name": "蒂姆·罗宾斯",
        |                    "id": "1054521"
        |                },
        |                {
        |                    "alt": "https://movie.douban.com/celebrity/1054534/",
        |                    "avatars": {
        |                        "small": "https://img3.doubanio.com/img/celebrity/small/34642.jpg",
        |                        "large": "https://img3.doubanio.com/img/celebrity/large/34642.jpg",
        |                        "medium": "https://img3.doubanio.com/img/celebrity/medium/34642.jpg"
        |                    },
        |                    "name": "摩根·弗里曼",
        |                    "id": "1054534"
        |                },
        |                {
        |                    "alt": "https://movie.douban.com/celebrity/1041179/",
        |                    "avatars": {
        |                        "small": "https://img1.doubanio.com/img/celebrity/small/5837.jpg",
        |                        "large": "https://img1.doubanio.com/img/celebrity/large/5837.jpg",
        |                        "medium": "https://img1.doubanio.com/img/celebrity/medium/5837.jpg"
        |                    },
        |                    "name": "鲍勃·冈顿",
        |                    "id": "1041179"
        |                }
        |            ],
        |            "collect_count": 1135009,
        |            "original_title": "The Shawshank Redemption",
        |            "subtype": "movie",
        |            "directors": [
        |                {
        |                    "alt": "https://movie.douban.com/celebrity/1047973/",
        |                    "avatars": {
        |                        "small": "https://img3.doubanio.com/img/celebrity/small/230.jpg",
        |                        "large": "https://img3.doubanio.com/img/celebrity/large/230.jpg",
        |                        "medium": "https://img3.doubanio.com/img/celebrity/medium/230.jpg"
        |                    },
        |                    "name": "弗兰克·德拉邦特",
        |                    "id": "1047973"
        |                }
        |            ],
        |            "year": "1994",
        |            "images": {
        |                "small": "https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p480747492.webp",
        |                "large": "https://img3.doubanio.com/view/movie_poster_cover/lpst/public/p480747492.webp",
        |                "medium": "https://img3.doubanio.com/view/movie_poster_cover/spst/public/p480747492.webp"
        |            },
        |            "alt": "https://movie.douban.com/subject/1292052/",
        |            "id": "1292052"
        |        },
        |        {
        |            "rating": {
        |                "max": 10,
        |                "average": 9.5,
        |                "stars": "50",
        |                "min": 0
        |            },
        |            "genres": [
        |                "剧情",
        |                "爱情",
        |                "同性"
        |            ],
        |            "title": "霸王别姬",
        |            "casts": [
        |                {
        |                    "alt": "https://movie.douban.com/celebrity/1003494/",
        |                    "avatars": {
        |                        "small": "https://img1.doubanio.com/img/celebrity/small/67.jpg",
        |                        "large": "https://img1.doubanio.com/img/celebrity/large/67.jpg",
        |                        "medium": "https://img1.doubanio.com/img/celebrity/medium/67.jpg"
        |                    },
        |                    "name": "张国荣",
        |                    "id": "1003494"
        |                },
        |                {
        |                    "alt": "https://movie.douban.com/celebrity/1050265/",
        |                    "avatars": {
        |                        "small": "https://img3.doubanio.com/img/celebrity/small/46345.jpg",
        |                        "large": "https://img3.doubanio.com/img/celebrity/large/46345.jpg",
        |                        "medium": "https://img3.doubanio.com/img/celebrity/medium/46345.jpg"
        |                    },
        |                    "name": "张丰毅",
        |                    "id": "1050265"
        |                },
        |                {
        |                    "alt": "https://movie.douban.com/celebrity/1035641/",
        |                    "avatars": {
        |                        "small": "https://img1.doubanio.com/img/celebrity/small/1399268395.47.jpg",
        |                        "large": "https://img1.doubanio.com/img/celebrity/large/1399268395.47.jpg",
        |                        "medium": "https://img1.doubanio.com/img/celebrity/medium/1399268395.47.jpg"
        |                    },
        |                    "name": "巩俐",
        |                    "id": "1035641"
        |                }
        |            ],
        |            "collect_count": 810842,
        |            "original_title": "霸王别姬",
        |            "subtype": "movie",
        |            "directors": [
        |                {
        |                    "alt": "https://movie.douban.com/celebrity/1023040/",
        |                    "avatars": {
        |                        "small": "https://img3.doubanio.com/img/celebrity/small/750.jpg",
        |                        "large": "https://img3.doubanio.com/img/celebrity/large/750.jpg",
        |                        "medium": "https://img3.doubanio.com/img/celebrity/medium/750.jpg"
        |                    },
        |                    "name": "陈凯歌",
        |                    "id": "1023040"
        |                }
        |            ],
        |            "year": "1993",
        |            "images": {
        |                "small": "https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p1910813120.webp",
        |                "large": "https://img3.doubanio.com/view/movie_poster_cover/lpst/public/p1910813120.webp",
        |                "medium": "https://img3.doubanio.com/view/movie_poster_cover/spst/public/p1910813120.webp"
        |            },
        |            "alt": "https://movie.douban.com/subject/1291546/",
        |            "id": "1291546"
        |        }
        |   ]
        |}
      """.stripMargin.parseJson //
 import ResultJsonProtocol._
 val top250 = jsonValue.convertTo[Top250]
 println("count:" + top250.count + ";start" + top250.start + ";start:" + top250.total + ";title:" + top250.title)
 top250.subjects.foreach(item => println(item.title))

完整示例参考我的github上正在开发的项目Scalandroid

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容