android scala,用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的缘故。

10c25fd4bdf1

jvm版本设置

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

10c25fd4bdf1

检查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定义对应的实体类,一般scala用case class,类似于java中的JavaBean、kotlin中的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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Scala解析 JSON 可以使用多种库,其中最常用的是 `Play JSON` 和 `Circe`。下面我将为你提供两种常见的解析方式。 1. 使用 Play JSON: 首先,你需要在项目的 build.sbt 文件中添加以下依赖项: ```scala libraryDependencies += "com.typesafe.play" %% "play-json" % "2.9.2" ``` 然后,你可以按照以下步骤解析 JSON: ```scala import play.api.libs.json._ // 定义一个 case class 表示你的 JSON 结构 case class Person(name: String, age: Int) // 创建一个 Json Reads 实例用于解析 JSON implicit val personReads: Reads[Person] = Json.reads[Person] // 解析 JSON val jsonStr = """{"name": "John", "age": 30}""" val json = Json.parse(jsonStr) val personResult = json.validate[Person] personResult match { case JsSuccess(person, _) => println(person) // 解析成功 case JsError(errors) => println(errors) // 解析失败 } ``` 2. 使用 Circe: 首先,你需要在项目的 build.sbt 文件中添加以下依赖项: ```scala libraryDependencies += "io.circe" %% "circe-core" % "0.14.1" libraryDependencies += "io.circe" %% "circe-generic" % "0.14.1" ``` 然后,你可以按照以下步骤解析 JSON: ```scala import io.circe._ import io.circe.parser._ import io.circe.generic.auto._ // 定义一个 case class 表示你的 JSON 结构 case class Person(name: String, age: Int) // 解析 JSON val jsonStr = """{"name": "John", "age": 30}""" val json = parse(jsonStr).getOrElse(Json.Null) val personResult = json.as[Person] personResult match { case Right(person) => println(person) // 解析成功 case Left(error) => println(error) // 解析失败 } ``` 以上是两种常见的解析 JSON 的方式,你可以根据自己的需求选择适合的库和方法。希望对你有所帮助!如果还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值