首页 > 解决方案 > 使用 Retrofit 进行两次 API 调用以形成一个对象

问题描述

我正在编写一个应用程序,不幸的是,它需要两次 API 调用才能完成一个对象。一次调用 TMDB 以获取当前在影院上映的电影列表,然后再次调用 TMDB 并使用每部电影的 TMDB ID 获取 IMDB ID。

稍后我可能还想对 OMDB 进行第三次调用以从那里获取数据,因为这是我们在电影页面本身上使用的数据。

我是 RXJava 的新手,对 Retrofit 还很陌生。我用老式的方式(嗯,我使用了 OKHTTP)做到了这一点,但我想用 RXJava 切换到更优雅的版本,这对我来说似乎是一个完美的用例。

第一次 API 调用示例

https://api.themoviedb.org/3/movie/now_playing?api_key={key}&language=en-US&page=1&region=US

JSON 响应

{
"results":[
    {
        "vote_count":425,
        "id":345940,
        "video":false,
        "vote_average":6.2,
        "title":"The Meg",
        "popularity":164.309,
        "poster_path":"/xqECHNvzbDL5I3iiOVUkVPJMSbc.jpg",
        "original_language":"en",
        "original_title":"The Meg",
        "genre_ids":[
            28,
            878,
            53,
            27
        ],
        "backdrop_path":"/ibKeXahq4JD63z6uWQphqoJLvNw.jpg",
        "adult":false,
        "overview":"A deep sea submersible pilot revisits his past fears in the Mariana Trench, and accidentally unleashes the seventy foot ancestor of the Great White Shark believed to be extinct.",
        "release_date":"2018-08-10"
    },
    {
        "vote_count":1027,
        "id":353081,
        "video":false,
        "vote_average":7.4,
        "title":"Mission: Impossible - Fallout",
        "popularity":137.095,
        "poster_path":"/AkJQpZp9WoNdj7pLYSj1L0RcMMN.jpg",
        "original_language":"en",
        "original_title":"Mission: Impossible - Fallout",
        "genre_ids":[
            12,
            28,
            53
        ],
        "backdrop_path":"/5qxePyMYDisLe8rJiBYX8HKEyv2.jpg",
        "adult":false,
        "overview":"When an IMF mission ends badly, the world is faced with dire consequences. As Ethan Hunt takes it upon himself to fulfil his original briefing, the CIA begin to question his loyalty and his motives. The IMF team find themselves in a race against time, hunted by assassins while trying to prevent a global catastrophe.",
        "release_date":"2018-07-27"
    },
    {
        "vote_count":473,
        "id":447200,
        "video":false,
        "vote_average":6,
        "title":"Skyscraper",
        "popularity":58.382,
        "poster_path":"/5LYSsOPzuP13201qSzMjNxi8FxN.jpg",
        "original_language":"en",
        "original_title":"Skyscraper",
        "genre_ids":[
            28,
            53,
            18
        ],
        "backdrop_path":"/oMKFQmoVgB69fyXfSMu0lGlHJP2.jpg",
        "adult":false,
        "overview":"Framed and on the run, a former FBI agent must save his family from a blazing fire in the world's tallest building.",
        "release_date":"2018-07-13"
    },
    {
        "vote_count":20,
        "id":399360,
        "video":false,
        "vote_average":5.3,
        "title":"Alpha",
        "popularity":54.434,
        "poster_path":"/afdZAIcAQscziqVtsEoh2PwsYTW.jpg",
        "original_language":"en",
        "original_title":"Alpha",
        "genre_ids":[
            53,
            12,
            18
        ],
        "backdrop_path":"/nKMeTdm72LQ756Eq20uTjF1zDXu.jpg",
        "adult":false,
        "overview":"After a hunting expedition goes awry, a young caveman struggles against the elements to find his way home.",
        "release_date":"2018-08-17"
    },
    {
        "vote_count":14,
        "id":476292,
        "video":false,
        "vote_average":4.9,
        "title":"Maquia: When the Promised Flower Blooms",
        "popularity":47.674,
        "poster_path":"/qcnOKCPleLOTWPPgYI0YT1MOQwR.jpg",
        "original_language":"ja",
        "original_title":"さよならの朝に約束の花をかざろう",
        "genre_ids":[
            16
        ],
        "backdrop_path":"/cfbjFQ14hSTgXChBEvaEjFiUaKb.jpg",
        "adult":false,
        "overview":"A story of encounters and partings interwoven between people; this is a human drama with feelings that touch one's heart gradually, which everyone has experienced at least once.",
        "release_date":"2018-07-20"
    },
    {
        "vote_count":312,
        "id":345887,
        "video":false,
        "vote_average":6.3,
        "title":"The Equalizer 2",
        "popularity":41.975,
        "poster_path":"/cQvc9N6JiMVKqol3wcYrGshsIdZ.jpg",
        "original_language":"en",
        "original_title":"The Equalizer 2",
        "genre_ids":[
            53,
            28,
            80
        ],
        "backdrop_path":"/z6KLDE72SxE1A8JcJTmmnWArOvR.jpg",
        "adult":false,
        "overview":"Robert McCall returns to deliver his special brand of vigilante justice -- but how far will he go when it's someone he loves?",
        "release_date":"2018-07-20"
    },
    {
        "vote_count":59,
        "id":455207,
        "video":false,
        "vote_average":7.2,
        "title":"Crazy Rich Asians",
        "popularity":33.287,
        "poster_path":"/gnTqi4nhIi1eesT5uYMmhEPGNih.jpg",
        "original_language":"en",
        "original_title":"Crazy Rich Asians",
        "genre_ids":[
            35
        ],
        "backdrop_path":"/zeHB7aP46Xs3u4aFLuAq2GFeUGb.jpg",
        "adult":false,
        "overview":"An American-born Chinese economics professor accompanies her boyfriend to Singapore for his best friend's wedding, only to get thrust into the lives of Asia's rich and famous.",
        "release_date":"2018-08-15"
    },
    {
        "vote_count":7,
        "id":385448,
        "video":false,
        "vote_average":5.2,
        "title":"The Little Mermaid",
        "popularity":29.657,
        "poster_path":"/1scpzHhPWDuRc21ci6Tfv5zfKnH.jpg",
        "original_language":"en",
        "original_title":"The Little Mermaid",
        "genre_ids":[
            12,
            14,
            10749,
            18
        ],
        "backdrop_path":"/7UY85MIj5IBOGhzL2kNByn7mSBj.jpg",
        "adult":false,
        "overview":"A young reporter and his niece discover a beautiful and enchanting creature they believe to be the real little mermaid.",
        "release_date":"2018-08-17"
    },
    {
        "vote_count":85,
        "id":487558,
        "video":false,
        "vote_average":7.6,
        "title":"BlacKkKlansman",
        "popularity":29.592,
        "poster_path":"/lTgROqb5nrzILPRjUY6JjDIrOhh.jpg",
        "original_language":"en",
        "original_title":"BlacKkKlansman",
        "genre_ids":[
            80,
            18,
            35,
            36
        ],
        "backdrop_path":"/gMVdhfQ7q9DFHhDkehrququjGPd.jpg",
        "adult":false,
        "overview":"Ron Stallworth, an African-American police officer from Colorado, successfully manages to infiltrate the local Ku Klux Klan and become the head of the local chapter.",
        "release_date":"2018-08-10"
    },
    {
        "vote_count":394,
        "id":400155,
        "video":false,
        "vote_average":6.9,
        "title":"Hotel Transylvania 3: Summer Vacation",
        "popularity":29.384,
        "poster_path":"/gjAFM4xhA5vyLxxKMz38ujlUfDL.jpg",
        "original_language":"en",
        "original_title":"Hotel Transylvania 3: Summer Vacation",
        "genre_ids":[
            10751,
            14,
            35,
            16
        ],
        "backdrop_path":"/m03jul0YdVEOFXEQVUv6pOVQYGL.jpg",
        "adult":false,
        "overview":"Dracula, Mavis, Johnny and the rest of the Drac Pack take a vacation on a luxury Monster Cruise Ship, where Dracula falls in love with the ship's captain, Ericka, who's secretly a descendant of Abraham Van Helsing, the notorious monster slayer.",
        "release_date":"2018-06-30"
    },
    {
        "vote_count":101,
        "id":420814,
        "video":false,
        "vote_average":7.2,
        "title":"Christopher Robin",
        "popularity":26.982,
        "poster_path":"/xR5w0he6czZkcAz459a4iPBqXGe.jpg",
        "original_language":"en",
        "original_title":"Christopher Robin",
        "genre_ids":[
            16,
            12,
            35
        ],
        "backdrop_path":"/uDt8bQ4lGVlabEx5Gl2cPzvy6qz.jpg",
        "adult":false,
        "overview":"Working-class family man Christopher Robin encounters his childhood friend Winnie-the-Pooh, who helps him to rediscover the joys of life.",
        "release_date":"2018-08-03"
    },
    {
        "vote_count":435,
        "id":458423,
        "video":false,
        "vote_average":7.8,
        "title":"Mamma Mia! Here We Go Again",
        "popularity":25.931,
        "poster_path":"/aWicerX4Y7n7tUwRAVHsVcBBpj2.jpg",
        "original_language":"en",
        "original_title":"Mamma Mia! Here We Go Again",
        "genre_ids":[
            35,
            10749,
            10402
        ],
        "backdrop_path":"/8HKwxHZ23sW8wz4yb28IWnAM1M6.jpg",
        "adult":false,
        "overview":"Five years after meeting her three fathers, Sophie Sheridan prepares to open her mother’s hotel. In 1979, young Donna Sheridan meets the men who each could be Sophie’s biological father.",
        "release_date":"2018-07-20"
    },
    {
        "vote_count":101,
        "id":454992,
        "video":false,
        "vote_average":6.4,
        "title":"The Spy Who Dumped Me",
        "popularity":24.345,
        "poster_path":"/2lIr27lBdxCpzYDl6WUHzzD6l6H.jpg",
        "original_language":"en",
        "original_title":"The Spy Who Dumped Me",
        "genre_ids":[
            28,
            35
        ],
        "backdrop_path":"/9CqzJn0nLaDNM6QWfGkuox2Oi93.jpg",
        "adult":false,
        "overview":"Audrey and Morgan are best friends who unwittingly become entangled in an international conspiracy when one of the women discovers the boyfriend who dumped her was actually a spy.",
        "release_date":"2018-08-03"
    },
    {
        "vote_count":9,
        "id":438590,
        "video":false,
        "vote_average":2.4,
        "title":"A.X.L.",
        "popularity":23.706,
        "poster_path":"/9kB56ZdMB6RgY5QtX9Bar45jCeI.jpg",
        "original_language":"en",
        "original_title":"A.X.L.",
        "genre_ids":[
            878
        ],
        "backdrop_path":"/l1nYo0yzKjf84atnBDbx0do16vQ.jpg",
        "adult":false,
        "overview":"The life of a teenage boy is forever altered by a chance encounter with cutting edge military technology.",
        "release_date":"2018-08-24"
    },
    {
        "vote_count":184,
        "id":445651,
        "video":false,
        "vote_average":6.8,
        "title":"The Darkest Minds",
        "popularity":20.9,
        "poster_path":"/94RaS52zmsqaiAe1TG20pdbJCZr.jpg",
        "original_language":"en",
        "original_title":"The Darkest Minds",
        "genre_ids":[
            878,
            53
        ],
        "backdrop_path":"/5BxrMNGl3YDiWgHCVJu8iLQoJDM.jpg",
        "adult":false,
        "overview":"After a disease kills 98% of America's children, the surviving 2% develop superpowers and are placed in internment camps. A 16-year-old girl escapes her camp and joins a group of other teens on the run from the government.",
        "release_date":"2018-08-03"
    },
    {
        "vote_count":5,
        "id":489999,
        "video":false,
        "vote_average":5.2,
        "title":"Searching",
        "popularity":20.762,
        "poster_path":"/9N0T3BaHZNdUCcMZQIM3yMUFwEh.jpg",
        "original_language":"en",
        "original_title":"Searching",
        "genre_ids":[
            18,
            53
        ],
        "backdrop_path":"/1q5AauYD1szopz5qnd6qqxnpTHG.jpg",
        "adult":false,
        "overview":"After his 16-year-old daughter goes missing, a desperate father breaks into her laptop to look for clues to find her. A thriller that unfolds entirely on computer screens.",
        "release_date":"2018-08-24"
    },
    {
        "vote_count":20,
        "id":347375,
        "video":false,
        "vote_average":5.1,
        "title":"Mile 22",
        "popularity":19.505,
        "poster_path":"/2L8ehd95eSW9x7KINYtZmRkAlrZ.jpg",
        "original_language":"en",
        "original_title":"Mile 22",
        "genre_ids":[
            28
        ],
        "backdrop_path":"/wWoCid7YUxiLhq3ZZT6CtFEDPXw.jpg",
        "adult":false,
        "overview":"A CIA field officer and an Indonesian police officer are forced to work together in confronting political corruption. An informant must be moved twenty-two miles to safety.",
        "release_date":"2018-08-17"
    },
    {
        "vote_count":28,
        "id":439015,
        "video":false,
        "vote_average":4.3,
        "title":"Slender Man",
        "popularity":18.529,
        "poster_path":"/huSncs4RyvQDBmHjBBYHSBYJbSJ.jpg",
        "original_language":"en",
        "original_title":"Slender Man",
        "genre_ids":[
            27
        ],
        "backdrop_path":"/5K0fgMaJSdEvqSsS8e3Ez4TpvXR.jpg",
        "adult":false,
        "overview":"In a small town in Massachusetts, four high school girls perform a ritual in an attempt to debunk the lore of Slender Man. When one of the girls goes mysteriously missing, they begin to suspect that she is, in fact, his latest victim.",
        "release_date":"2018-08-10"
    },
    {
        "vote_count":1,
        "id":456086,
        "video":false,
        "vote_average":0,
        "title":"Support the Girls",
        "popularity":17.759,
        "poster_path":"/leS393QLCe9UyY9TuWT8OvwuNk1.jpg",
        "original_language":"en",
        "original_title":"Support the Girls",
        "genre_ids":[
            18
        ],
        "backdrop_path":"/wMiJPxdZ4avOtqijP62T6yR1wqo.jpg",
        "adult":false,
        "overview":"Lisa Conroy may not love managing the restaurant Double Whammies, but she loves her employees more than anything, not only Danyelle, and Maci, her closest friends, but also her extended family. Unfortunately, the cheap, curmudgeonly owner Ben Cubby doesn’t care nearly as much, and confronts Lisa when he learns that she’s using the restaurant to raise money for Shaina, an employee in legal trouble related to an abusive boyfriend. To get even, the girls decide to sabotage the restaurant on the night of a major mixed martial arts fight.",
        "release_date":"2018-08-24"
    },
    {
        "vote_count":0,
        "id":450484,
        "video":false,
        "vote_average":0,
        "title":"An L.A. Minute",
        "popularity":17.665,
        "poster_path":"/aI2CN1QloY8ZWdeNJac7EQjeHkt.jpg",
        "original_language":"en",
        "original_title":"An L.A. Minute",
        "genre_ids":[

        ],
        "backdrop_path":null,
        "adult":false,
        "overview":"Best-selling author Ted Gold faces a moral dilemma when Velocity, an avant-garde performance artist and the living embodiment of integrity, rocks his 1% world.",
        "release_date":"2018-08-24"
    }
],
"page":1,
"total_results":124,
"dates":{
    "maximum":"2018-08-29",
    "minimum":"2018-07-12"
},
"total_pages":7
}

获取 IMDB id 的第二个 API 调用示例

https://api.themoviedb.org/3/movie/345940?api_key={api_key}&language=en-US

JSON 响应

{
"adult":false,
"backdrop_path":"/ibKeXahq4JD63z6uWQphqoJLvNw.jpg",
"belongs_to_collection":null,
"budget":150000000,
"genres":[
    {
        "id":28,
        "name":"Action"
    },
    {
        "id":878,
        "name":"Science Fiction"
    },
    {
        "id":53,
        "name":"Thriller"
    },
    {
        "id":27,
        "name":"Horror"
    }
],
"homepage":"http://www.themeg.movie",
"id":345940,
"imdb_id":"tt4779682",
"original_language":"en",
"original_title":"The Meg",
"overview":"A deep sea submersible pilot revisits his past fears in the Mariana Trench, and accidentally unleashes the seventy foot ancestor of the Great White Shark believed to be extinct.",
"popularity":164.309,
"poster_path":"/xqECHNvzbDL5I3iiOVUkVPJMSbc.jpg",
"production_companies":[
    {
        "id":56241,
        "logo_path":null,
        "name":"Maeday Productions",
        "origin_country":""
    },
    {
        "id":56242,
        "logo_path":"/1YORRYmg7hgYIgoJek8jU3cykuQ.png",
        "name":"Apelles Entertainment",
        "origin_country":"US"
    },
    {
        "id":48778,
        "logo_path":"/tto2UKph873Xh1ytxfNBgCxT8NO.png",
        "name":"Gravity Pictures",
        "origin_country":"CN"
    },
    {
        "id":435,
        "logo_path":null,
        "name":"Di Bonaventura Pictures",
        "origin_country":"US"
    },
    {
        "id":107790,
        "logo_path":null,
        "name":"Flagship Entertainment Group",
        "origin_country":"CN"
    }
],
"production_countries":[
    {
        "iso_3166_1":"CN",
        "name":"China"
    },
    {
        "iso_3166_1":"US",
        "name":"United States of America"
    }
],
"release_date":"2018-08-09",
"revenue":141500000,
"runtime":113,
"spoken_languages":[
    {
        "iso_639_1":"en",
        "name":"English"
    }
],
"status":"Released",
"tagline":"Chomp On This",
"title":"The Meg",
"video":false,
"vote_average":6.2,
"vote_count":426
}

电影对象

package watch.trigger.Model;

import com.google.gson.annotations.SerializedName;

/**
 * Created by paxie on 10/7/17.
 */

public class Movie {

    private String imdbID;
    @SerializedName("Title")
    private String title;
    @SerializedName("Year")
    private String year;
    private String summary;
    private String mpaaRating;
    private double imdbRating;
    @SerializedName("Poster")
    private String posterURL;


    private String award;

    public Movie(String imdbID, String title, String year, String posterURL, String award) {
        this.imdbID = imdbID;
        this.title = title;
        this.year = year;
        this.posterURL = posterURL;
        this.award = award;
    }

    public Movie(String imdbID) {
        this.imdbID = imdbID;
    }

    public Movie(String imdbID, String title) {
        this.imdbID = imdbID;
        this.title = title;
    }

    public Movie() {
    }

    public String getImdbID() {
        return imdbID;
    }

    public void setImdbID(String imdbID) {
        this.imdbID = imdbID;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getYear() {
        return year;
    }

    public void setYear(String year) {
        this.year = year;
    }

    public String getSummary() {
        return summary;
    }

    public void setSummary(String summary) {
        this.summary = summary;
    }

    public String getMpaaRating() {
        return mpaaRating;
    }

    public void setMpaaRating(String mpaaRating) {
        this.mpaaRating = mpaaRating;
    }

    public double getImdbRating() {
        return imdbRating;
    }

    public void setImdbRating(double imdbRating) {
        this.imdbRating = imdbRating;
    }

    public String getPosterURL() {
        return posterURL;
    }

    public void setPosterURL(String posterURL) {
        this.posterURL = posterURL;
    }

    public String getAward() {
        return award;
    }

    public void setAward(String award) {
        this.award = award;
    }

}

标签: androidrestretrofit2rx-java2

解决方案


对三个网络调用执行一次combineLatest并将它们包装在一个对象中,然后在订阅中将值拉出到您的最终对象中并将其发送给您的演示者或显示或其他业务逻辑

 Observable.combineLatest(
        networkCallOne().take(1),
        networkCallTwo().take(1),
        networkCallThree().take(1),
        (obj1, obj2, obj3) -> new WrapperObject(obj1, obj2, obj3))
              .observeOn(Schedulers.io())
              .take(1)
              .subscribeOn(AndroidSchedulers.mainThread())
              .subscribe(wrapperObj -> {
                //do some logic
              })

对于 combineLatest

当任何一个 Observable 发出一个 item 时,通过一个指定的函数组合每个 Observable 发出的最新 item,并根据这个函数的结果发出 item

这将等到所有 3 个网络调用都返回,然后结合最新的值

而 take(1) 只会确保您只获得 1 个值。一定要处理错误,因为这不会为您做到这一点


推荐阅读