我目前正在首次尝试将RxJava与Retrofit结合使用,但似乎无法满足我的特定用例的要求:
我首先使用改造来调用API,以向用户所在位置附近的电影院放映电影。 然后,我使用用户单击的电影院ID来显示该电影院的放映时间,即...
public interface ListingApiService
{
@GET("/get/times/cinema/{id}")
Call<ListingResponse> getShowtimes (@Path("id") String id);
}
Then using the interface....
public void connectAndGetApiData(String id)
{
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
ListingApiService listingApiService = retrofit.create(ListingApiService.class);
Call<ListingResponse> call = listingApiService.getShowtimes(id);
call.enqueue(new Callback<ListingResponse>() {
@Override
public void onResponse(Call<ListingResponse> call, Response<ListingResponse> response)
{
List<Listing> listings = response.body().getListings()
getAndDisplayImage(listings.get(0).getTitle());
recyclerView.setAdapter(new ListingAdapter(listings,R.layout.list_item_listing,getApplicationContext()));
}
@Override
public void onFailure(Call<ListingResponse> call, Throwable t)
{
Log.e(TAG,t.toString());
}
});
}
然后,我想调用一个不同的API(上下文网络搜索)以显示每个电影列表的相关电影海报的图像(只是为了获得良好的视觉效果)。我知道如何为单个图像调用API,但是我不知道如何进行多个调用。我尝试使用Internet上其他地方找到的RxJava代码,但似乎都不起作用,因为我不知道我将要拨打多少电话或搜索字词是什么。我用于单次通话的代码是:
public interface ListingImageApiService
{
//https://contextualwebsearch-websearch-v1.p.mashape.com/api/Search/ImageSearchAPI?count=1&autoCorrect=false&q=Donald+Trump
@Headers("X-Mashape-Key: apikey")
@GET("/api/Search/ImageSearchAPI?count=5&autoCorrect=false")
Call<ListingImageResponse> getListingImages (@Query("q") String term);
}
public void getAndDisplayImage(String search)
{
if (retrofit2 == null)
{
retrofit2 = new Retrofit.Builder()
.baseUrl(BASE_URL2)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
search = search + " poster";
ListingImageApiService listingImageApiService = retrofit2.create(ListingImageApiService.class);
Call<ListingImageResponse> call = listingImageApiService.getListingImages(search);
call.enqueue(new Callback<ListingImageResponse>() {
@Override
public void onResponse(Call<ListingImageResponse> call, Response<ListingImageResponse> response)
{
System.out.println(response.body().toString());
ListingImage a = new ListingImage();
List<ListingImage> listingImages = response.body().getListingImage();
System.out.println(listingImages.get(0).getUrl());
}
@Override
public void onFailure(Call<ListingImageResponse> call, Throwable t)
{
}
});
}
我的问题是,我将如何使用RxJava使用未知大小的电影标题列表的数据进行多次调用(可以将其传递给getAndDisplayImage而不是单个字符串)?我做了几次尝试,但是似乎都没有用到我的用例。谢谢。
答案 0 :(得分:2)
这种设计应该可以解决您的问题。
此接口包含应用程序中使用的端点。
public interface ListingApiService
{
@GET("/get/times/cinema/{id}")
Observable<List<MovieResponse>> getShowtimes (@Path("id") String id);
@Headers("X-Mashape-Key: apikey")
@GET("/api/Search/ImageSearchAPI?count=5&autoCorrect=false")
Observable<ListingImageResponse> getListingImages (@Query("q") String term);
}
提供改造对象以进行呼叫的方法
private API getAPI() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("<your API endpoint address")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
return retrofit.create(API.class);
}
拨打电话以获取List<MovieResponse>
。此方法还将List
转换为单个可观察的MovieResponse
对象。
private void getMovieListingsWithImages() {
Observer<MovieResponse> observer = new Observer<MovieResponse>() {
@Override
public void onSubscribe(Disposable d) {
Toast.makeText(getApplicationContext(), "", Toast.LENGTH_SHORT).show();
}
@Override
public void onNext(MovieResponse movieResponse) {
//for each movie response make a call to the API which provides the image for the movie
}
@Override
public void onError(Throwable e) {
Toast.makeText(getApplicationContext(), "Error getting image for the movie", Toast.LENGTH_SHORT).show();
}
@Override
public void onComplete() {
Toast.makeText(getApplicationContext(), "Finished getting images for all the movies in the stream", Toast.LENGTH_SHORT).show();
}
};
getAPI().getShowtimes()
.flatMapIterable(movieResponseList -> movieResponseList) // converts your list of movieResponse into and observable which emits one movieResponse object at a time.
.flatMap(this::getObservableFromString) // method converts the each movie response object into an observable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer);
}
将MovieResponse
对象转换为Observable
对象的方法。
private Observable<MovieResponse> getObservableFromString(MovieResponse movieResponse) {
return Observable.just(movieResponse);
}