Android 为未知大小列表中的每一项调用RxJava/改型API
我目前第一次尝试使用RxJava进行改装,但似乎无法使任何东西适合我的特定用例: 我首先调用一个API,使用改造来显示用户位置附近的电影院。 然后我使用用户点击的影院id来显示该影院的放映时间,即Android 为未知大小列表中的每一项调用RxJava/改型API,android,api,rx-java,retrofit2,rx-java2,Android,Api,Rx Java,Retrofit2,Rx Java2,我目前第一次尝试使用RxJava进行改装,但似乎无法使任何东西适合我的特定用例: 我首先调用一个API,使用改造来显示用户位置附近的电影院。 然后我使用用户点击的影院id来显示该影院的放映时间,即 public interface ListingApiService { @GET("/get/times/cinema/{id}") Call<ListingResponse> getShowtimes (@Path("id") String id); } Then
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());
}
});
}
公共接口列表服务
{
@GET(“/GET/times/cinema/{id}”)
调用getShowtimes(@Path(“id”)字符串id);
}
然后使用接口。。。。
public void connectAndGetApiData(字符串id)
{
如果(改装==null){
改装=新改装.Builder()
.baseUrl(基本URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
ListingApiService ListingApiService=reformation.create(ListingApiService.class);
Call Call=listingApiService.getShowtimes(id);
call.enqueue(新回调(){
@凌驾
公共void onResponse(调用、响应)
{
列表列表=response.body().getListings()
getAndDisplayImage(listings.get(0.getTitle());
setAdapter(新的ListingAdapter(listings,R.layout.list_item_listing,getApplicationContext());
}
@凌驾
失败时公共无效(调用调用,可丢弃的t)
{
Log.e(TAG,t.toString());
}
});
}
然后我想调用一个不同的API(上下文web搜索),为每个电影列表显示相关电影海报的图像(只是为了获得良好的视觉效果)。我知道如何为单个映像调用API,但不知道如何进行多个调用。我尝试过使用互联网上其他地方的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)
{
}
});
}
公共接口列表ImageAPI服务
{
//https://contextualwebsearch-websearch-v1.p.mashape.com/api/Search/ImageSearchAPI?count=1&autoCorrect=false&q=Donald+特朗普
@标题(“X-Mashape-Key:apikey”)
@GET(“/api/Search/ImageSearchAPI?count=5&autoCorrect=false”)
调用getListingImages(@Query(“q”)字符串术语);
}
public void getAndDisplayImage(字符串搜索)
{
如果(2==null)
{
Refught2=新改型.Builder()
.baseUrl(BASE_URL2)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
搜索=搜索+海报;
ListingImageApiService ListingImageApiService=2.create(ListingImageApiService.class);
Call Call=ListingImageApisService.getListingImages(搜索);
call.enqueue(新回调(){
@凌驾
公共void onResponse(调用、响应)
{
System.out.println(response.body().toString());
ListingImage a=新建ListingImage();
List listingImages=response.body().getListingImage();
System.out.println(listingImages.get(0.getUrl());
}
@凌驾
失败时公共无效(调用调用,可丢弃的t)
{
}
});
}
我的问题是,如何使用RxJava使用未知大小的电影标题列表(我可以传递给getAndDisplayImage而不是单个字符串)的数据进行多个调用?我做了几次尝试,但没有一次对我的用例有效。谢谢。这种设计应该能解决您的问题 此接口包含应用程序中使用的端点
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);
}
将MovieResponse
对象转换为可观察对象的方法
private Observable<MovieResponse> getObservableFromString(MovieResponse movieResponse) {
return Observable.just(movieResponse);
}
私有可观察getObservableFromString(MovieResponse MovieResponse){
返回可观察的。正义(movieResponse);
}
您是否使用了RxJava
中的map
操作符?从第一个api获取数据,并使用操作符和图像请求将结果转换为新的观察者。您好,我已经查看了map操作符,但我不知道它如何解决我的问题。我不知道如何对多个对象进行API调用。地图怎么能做到这一点?它不是简单地将函数应用于集合,还是我误解了map的用途?您好,感谢您花费时间和精力回复。因此,我实现了一些类似于您在这里建议的方法,在这里我使用类型Listing和flatmap创建一个可观察的Listing对象,该对象在onNext中重复,直到完成。这真的给了我实现RxJava所需的动力,再次感谢
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);
}
private Observable<MovieResponse> getObservableFromString(MovieResponse movieResponse) {
return Observable.just(movieResponse);
}