在Kotlin中使用Retrofit和RxJava 2获取JSON结果

时间:2018-10-11 17:17:18

标签: android mvvm kotlin retrofit rx-java2

我是Android / RX领域的新手,我正在制作一个使用MVVM架构在Kotlin中使用TMDB API的应用程序。

我的数据模型是:

    data class Credits ( val credits: MutableList<Details>)
    data class Details(@SerializedName("genres") val genres: MutableList<GenresResults>,
        @SerializedName("overview") val overview: String,
        @SerializedName("credits") val credits1: MutableList<CreditsResults>,
        @SerializedName("title") val title: String,
        @SerializedName("vote_average") val vote_average: Double,
        @SerializedName("backdrop_path") val backdrop: String,
        @SerializedName("id") val id: String)

包含get方法的数据接口是:

interface TMDBApiMovieDetails {
@GET("movie/{id}")
fun getDetails(@Path("id") id: Int,
        @Query("language") language: String,
        @Query("append_to_response") credits: String,
        @Query("api_key") api_key: String)
        : Observable<Details>

  companion object {
    fun create(): TMDBApiMovieDetails {
        val retrofit = Retrofit.Builder()
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create()).baseUrl("https://api.themoviedb.org/3/")
                .build()
        return retrofit.create(TMDBApiMovieDetails::class.java)
    }
}

在ViewModel中,我使用以下代码:

 class MovieDetailsViewModel( val tmdbApiMovieDetails: TMDBApiMovieDetails) 
 {

 private val refreshSubject: PublishSubject<Unit> = PublishSubject.create()
     private val basicApiCall: ConnectableObservable<MutableList<Details>>
private val compositeDisposable = CompositeDisposable()

    init {
        basicApiCall = refreshSubject

                .flatMap { return@flatMap tmdbApiMovieDetails.getDetails(id, "en-US","credits", api_key)
                        .map { it.credits}
                .subscribeOn(Schedulers.io())}
                .publish()
        compositeDisposable.add(basicApiCall.connect())
}
 fun getPopularMoviesRefreshObserver() : Observer<Unit> {
        return refreshSubject
    }

    fun getPopularMoviesRetrievedObservable() : Observable<MutableList<Details> {

        return basicApiCall
    }

最后,在相关活动(查看)中,我将其用于将结果传递到handleResponse(),它将填充相关的文本和图像字段。

presenter1.getPopularMoviesRefreshObserver().onNext(Unit)
    disposable = presenter1.getPopularMoviesRetrievedObservable()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe { handleResponse(it) }

问题是我遇到gson错误,提示:

  

期望BEGIN_ARRAY但在第1行1372列上为BEGIN_OBJECT

我知道这是指错误的数据模型定义,但我不知道如何正确定义它...

用简单的话来说,我想要的是Details数据类的内容是可引用的,以便我可以使用它们来填充我的details活动。

任何建议?

这是示例电影ID的json输出:

    {
  "adult": false,
  "backdrop_path": "/tQvvRReWhrXnj28s4AIp2PblByg.jpg",
  "belongs_to_collection": null,
  "budget": 42000000,
  "genres": [
    {
      "id": 27,
      "name": "Horror"
    },
    {
      "id": 14,
      "name": "Fantasy"
    },
    {
      "id": 53,
      "name": "Thriller"
    },
    {
      "id": 10751,
      "name": "Family"
    },
    {
      "id": 9648,
      "name": "Mystery"
    }
  ],
  "homepage": "http://housewithaclock.com",
  "id": 463821,
  "imdb_id": "tt2119543",
  "original_language": "en",
  "original_title": "The House with a Clock in Its Walls",
  "overview": "Ten-year-old Lewis goes to live with his uncle in a creaky old house that contains a mysterious ticktock noise. When Lewis accidentally awakens the dead, the town's sleepy facade magically springs to life with a secret world of witches and warlocks.",
  "popularity": 56.692,
  "poster_path": "/4MA86XWa0aYCwAu30qdvv3EyGBX.jpg",
  "production_companies": [
    {
      "id": 56,
      "logo_path": "/cEaxANEisCqeEoRvODv2dO1I0iI.png",
      "name": "Amblin Entertainment",
      "origin_country": "US"
    },
    {
      "id": 34982,
      "logo_path": "/uvTmiRZzNfG88dVXi9hQ7eFNirq.png",
      "name": "Mythology Entertainment",
      "origin_country": "US"
    }
  ],
  "production_countries": [
    {
      "iso_3166_1": "US",
      "name": "United States of America"
    }
  ],
  "release_date": "2018-09-15",
  "revenue": 29950000,
  "runtime": 105,
  "spoken_languages": [
    {
      "iso_639_1": "en",
      "name": "English"
    }
  ],
  "status": "Released",
  "tagline": "This house knows what makes you tick",
  "title": "The House with a Clock in Its Walls",
  "video": false,
  "vote_average": 6.4,
  "vote_count": 102,
  "credits": {
    "cast": [
      {
        "cast_id": 8,
        "character": "Lewis Barnavelt",
        "credit_id": "5a3c494792514154720a5b9f",
        "gender": 2,
        "id": 1552636,
        "name": "Owen Vaccaro",
        "order": 0,
        "profile_path": "/pNTtj9L4eVQQIb6o79D0dJC87HS.jpg"
      },
      {
        "cast_id": 0,
        "character": "Jonathan Barnavelt",
        "credit_id": "59545355c3a36814ae046f50",
        "gender": 2,
        "id": 70851,
        "name": "Jack Black",
        "order": 1,
        "profile_path": "/vMXgtzMdt2jSAjOECFQ5F53blbr.jpg"
      },
      {
        "cast_id": 4,
        "character": "Mrs. Zimmerman",
        "credit_id": "59947eadc3a3685ece001b21",
        "gender": 1,
        "id": 112,
        "name": "Cate Blanchett",
        "order": 2,
        "profile_path": "/5HikVWKfkkUa8aLdCMHtREBECIn.jpg"
      },
      {
        "cast_id": 5,
        "character": "Isaac Izard",
        "credit_id": "5a3c490d0e0a264cbe22a10f",
        "gender": 2,
        "id": 6677,
        "name": "Kyle MacLachlan",
        "order": 3,
        "profile_path": "/7DnMuDlSdpycAQQxOIDmV66qerc.jpg"
      },
      {
        "cast_id": 6,
        "character": "Mrs. Hanchett",
        "credit_id": "5a3c4929925141547b0a7e64",
        "gender": 1,
        "id": 13023,
        "name": "Colleen Camp",
        "order": 4,
        "profile_path": "/baASQgWewWYG7lnYjgjZXe2t5MM.jpg"
      },
      {
        "cast_id": 9,
        "character": "Tarby Corrigan",
        "credit_id": "5a6420f29251410b2d01afbd",
        "gender": 2,
        "id": 1444880,
        "name": "Sunny Suljic",
        "order": 5,
        "profile_path": "/tzHNISvgQNiMEd6rZnbtRGvFXuy.jpg"
      },
      {
        "cast_id": 7,
        "character": "Selena Izard",
        "credit_id": "5a3c49370e0a265f77030a41",
        "gender": 1,
        "id": 87932,
        "name": "Renée Elise Goldsberry",
        "order": 6,
        "profile_path": "/bNHksD4bZxWhNUIW5mwLgPWc30G.jpg"
      },
      {
        "cast_id": 10,
        "character": "Woody Mingo",
        "credit_id": "5abc28370e0a2609d801f1e9",
        "gender": 0,
        "id": 2004111,
        "name": "Braxton Bjerken",
        "order": 7,
        "profile_path": null
      },
      {
        "cast_id": 11,
        "character": "Lewis's Mother",
        "credit_id": "5abcf4540e0a2609ce028c88",
        "gender": 1,
        "id": 1078608,
        "name": "Lorenza Izzo",
        "order": 8,
        "profile_path": "/83WnfHu3B8M3EeZpjCgf9apDAAx.jpg"
      },
      {
        "cast_id": 12,
        "character": "Parent / Teacher",
        "credit_id": "5abcf4a4c3a36843960290d8",
        "gender": 0,
        "id": 2010423,
        "name": "Perla Middleton",
        "order": 9,
        "profile_path": null
      },
      {
        "cast_id": 13,
        "character": "Soda Jerk",
        "credit_id": "5abcf4ee0e0a2609d802c633",
        "gender": 2,
        "id": 1536821,
        "name": "Charles Green",
        "order": 10,
        "profile_path": "/9QUDEyCSDlzAdCl0zweSzDUSyqr.jpg"
      },
      {
        "cast_id": 14,
        "character": "Magicians Assistant",
        "credit_id": "5abcf50cc3a368439602913f",
        "gender": 0,
        "id": 2010428,
        "name": "Alli Beckman",
        "order": 11,
        "profile_path": null
      },
      {
        "cast_id": 15,
        "character": "Teen Pedestrian",
        "credit_id": "5abcf51fc3a3687cb701eb72",
        "gender": 0,
        "id": 2010430,
        "name": "Demetri Landell",
        "order": 12,
        "profile_path": null
      },
      {
        "cast_id": 16,
        "character": "Bus Driver",
        "credit_id": "5abcf52dc3a36843a6029510",
        "gender": 0,
        "id": 1181570,
        "name": "Ricky Muse",
        "order": 13,
        "profile_path": "/xThzRMWFym3eHMJ4mlWMEW367NX.jpg"
      },
      {
        "cast_id": 17,
        "character": "Townie",
        "credit_id": "5abcf552c3a368435c028df4",
        "gender": 0,
        "id": 1940429,
        "name": "Van Marten",
        "order": 14,
        "profile_path": null
      },
      {
        "cast_id": 18,
        "character": "Woody",
        "credit_id": "5abcf5610e0a2609db028f6c",
        "gender": 0,
        "id": 2010431,
        "name": "Jalyn Hall",
        "order": 15,
        "profile_path": null
      },
      {
        "cast_id": 19,
        "character": "Automaton",
        "credit_id": "5abcf5749251411ea00264d7",
        "gender": 0,
        "id": 1188389,
        "name": "Aaron Beelner",
        "order": 16,
        "profile_path": null
      },
      {
        "cast_id": 20,
        "character": "",
        "credit_id": "5abcf5850e0a2609d50293b8",
        "gender": 0,
        "id": 1842691,
        "name": "Chris Adams",
        "order": 17,
        "profile_path": "/xYyqz8opJ3PpB1Nq9uPY2CHK7aO.jpg"
      },
      {
        "cast_id": 21,
        "character": "Rose Rita Pottinger",
        "credit_id": "5abcf5a20e0a2609de027ef1",
        "gender": 0,
        "id": 2010434,
        "name": "Vanessa Anne Williams",
        "order": 18,
        "profile_path": null
      },
      {
        "cast_id": 22,
        "character": "Sweet Shop Boy",
        "credit_id": "5abcf5c2c3a3687cb701ec46",
        "gender": 0,
        "id": 2010437,
        "name": "Dylan Gage Moore",
        "order": 19,
        "profile_path": null
      },
      {
        "cast_id": 23,
        "character": "Sweet Shop Boy's Mother",
        "credit_id": "5abcf5db0e0a2609db028ff6",
        "gender": 0,
        "id": 2010439,
        "name": "Anela Terzic",
        "order": 20,
        "profile_path": null
      },
      {
        "cast_id": 24,
        "character": "Man sleeping on bus",
        "credit_id": "5abcf5f80e0a2609d802c72f",
        "gender": 0,
        "id": 2010440,
        "name": "Garrett Strobl",
        "order": 21,
        "profile_path": null
      },
      {
        "cast_id": 25,
        "character": "Soda Clerk",
        "credit_id": "5abcf6130e0a2609e102953e",
        "gender": 0,
        "id": 2010443,
        "name": "Caleb Lawrence",
        "order": 22,
        "profile_path": null
      },
      {
        "cast_id": 26,
        "character": "Student",
        "credit_id": "5abcf626c3a3684396029268",
        "gender": 0,
        "id": 2010446,
        "name": "Jack Giles IV",
        "order": 23,
        "profile_path": null
      },
      {
        "cast_id": 42,
        "character": "Comrade Ivan",
        "credit_id": "5b9e7623c3a368440801f000",
        "gender": 2,
        "id": 16847,
        "name": "Eli Roth",
        "order": 24,
        "profile_path": "/eHBxgJXeDKiYZMbL3VgAf7i9wor.jpg"
      }
    ],
    "crew": [
      {
        "credit_id": "595453b4c3a36809c60436ce",
        "department": "Writing",
        "gender": 2,
        "id": 58321,
        "job": "Screenplay",
        "name": "Eric Kripke",
        "profile_path": "/8L3BdDXPMvcAS0wZAyfpA5Vlg3l.jpg"
      },
      {
        "credit_id": "595453cdc3a36814ae047008",
        "department": "Writing",
        "gender": 0,
        "id": 1840992,
        "job": "Novel",
        "name": "John Bellairs",
        "profile_path": null
      },
      {
        "credit_id": "595453649251412b23041537",
        "department": "Directing",
        "gender": 2,
        "id": 16847,
        "job": "Director",
        "name": "Eli Roth",
        "profile_path": "/eHBxgJXeDKiYZMbL3VgAf7i9wor.jpg"
      },
      {
        "credit_id": "5abcf66f0e0a2609d5029490",
        "department": "Production",
        "gender": 2,
        "id": 20208,
        "job": "Producer",
        "name": "Brad Fischer",
        "profile_path": null
      },
      {
        "credit_id": "5abcf682c3a368435f024f23",
        "department": "Production",
        "gender": 1,
        "id": 20294,
        "job": "Executive Producer",
        "name": "Laeta Kalogridis",
        "profile_path": "/vfC4zu2BU6zAABpQZTnzbya2OGU.jpg"
      },
      {
        "credit_id": "5abcf695c3a36843960292f0",
        "department": "Production",
        "gender": 2,
        "id": 58321,
        "job": "Producer",
        "name": "Eric Kripke",
        "profile_path": "/8L3BdDXPMvcAS0wZAyfpA5Vlg3l.jpg"
      },
      {
        "credit_id": "5abcf6b30e0a2609db029103",
        "department": "Production",
        "gender": 0,
        "id": 1242779,
        "job": "Executive Producer",
        "name": "W. Mark McNair",
        "profile_path": null
      },
      {
        "credit_id": "5abcf6cbc3a368435f024f76",
        "department": "Production",
        "gender": 0,
        "id": 1953780,
        "job": "Executive Producer",
        "name": "Tracey Nyberg",
        "profile_path": null
      },
      {
        "credit_id": "5abcf6e39251411e9c026661",
        "department": "Production",
        "gender": 2,
        "id": 61122,
        "job": "Executive Producer",
        "name": "William Sherak",
        "profile_path": null
      },
      {
        "credit_id": "5abcf6f0c3a36843a60296cd",
        "department": "Production",
        "gender": 2,
        "id": 20204,
        "job": "Producer",
        "name": "James Vanderbilt",
        "profile_path": "/fAGhDGPqdCu5GDxFs6T8FoqqFms.jpg"
      },
      {
        "credit_id": "5abcf70dc3a3684362026de1",
        "department": "Sound",
        "gender": 2,
        "id": 19659,
        "job": "Music",
        "name": "Nathan Barr",
        "profile_path": null
      },
      {
        "credit_id": "5abcf71fc3a368435c028fe8",
        "department": "Crew",
        "gender": 2,
        "id": 17749,
        "job": "Cinematography",
        "name": "Rogier Stoffers",
        "profile_path": "/ouAYymfDLzsehrXDEPTpPsEwgVs.jpg"
      },
      {
        "credit_id": "5abcf7300e0a2609ce028f77",
        "department": "Production",
        "gender": 1,
        "id": 935278,
        "job": "Casting",
        "name": "Nicole Abellera",
        "profile_path": null
      },
      {
        "credit_id": "5abcf740c3a368438802a79d",
        "department": "Production",
        "gender": 1,
        "id": 546,
        "job": "Casting",
        "name": "Jeanne McCarthy",
        "profile_path": null
      },
      {
        "credit_id": "5abcf7509251411e9a025ca3",
        "department": "Art",
        "gender": 0,
        "id": 1530686,
        "job": "Art Direction",
        "name": "Andres Cubillan",
        "profile_path": null
      },
      {
        "credit_id": "5abcf75f0e0a2609e4027d9f",
        "department": "Art",
        "gender": 2,
        "id": 4147,
        "job": "Art Direction",
        "name": "Walter P. Martishius",
        "profile_path": null
      },
      {
        "credit_id": "5abcf76fc3a36843960293d1",
        "department": "Art",
        "gender": 1,
        "id": 1391639,
        "job": "Set Decoration",
        "name": "Ellen Brill",
        "profile_path": null
      },
      {
        "credit_id": "5abcf78d9251411e97025c11",
        "department": "Art",
        "gender": 0,
        "id": 1184340,
        "job": "Set Decoration",
        "name": "Tommy Wilson",
        "profile_path": null
      },
      {
        "credit_id": "5ba56249c3a368083d02110d",
        "department": "Editing",
        "gender": 0,
        "id": 71279,
        "job": "Editor",
        "name": "Andrew S. Eisen",
        "profile_path": null
      },
      {
        "credit_id": "5ba562539251412de301d8f7",
        "department": "Editing",
        "gender": 2,
        "id": 58194,
        "job": "Editor",
        "name": "Fred Raskin",
        "profile_path": null
      }
    ]
  }
}

1 个答案:

答案 0 :(得分:0)

建议您使用https://github.com/wuseal/JsonToKotlinClass从JSON创建数据类,并查看它创建的类是否为您正确解析。