android - 第二次未调用 RxJava Observable onNext
问题描述
我对 RxJava 很陌生。最近,我一直在尝试实现一段代码,该代码使用 Google Places Api 在所选半径内检索地点列表及其 ID,然后使用之前检索到的 ID 检索这些地点的详细信息。我在一个活动中有一个按钮,然后调用 Api 来检索信息。我的问题是,第一次单击按钮时调用 Api 并发出数据。在连续尝试时,不会触发 onNext,只调用 onComplete。
这是我使用 Retrofit 检索地点列表及其详细信息的界面代码
@Headers("Content-Type: application/json")
@GET("api/place/nearbysearch/json?radius=5000&key="+API_KEY)
Observable<PlacesResponse> getPlaces(@Query("location") String location, @Query("types") String types);
@Headers("Content-Type: application/json")
@GET("api/place/details/json?key="+API_KEY)
Observable<PlacesDetailsResponse> getPlaceDetails(@Query("placeid") String placeId);
然后我用它在我的活动的 onCreate 方法上启动 Api
private void initiateApi() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
.addConverterFactory(GsonConverterFactory.create())
.build();
mapService = retrofit.create(MapAPI.class);
}
我的活动中有一个搜索框和一个按钮。当输入搜索查询并单击按钮时,我调用此方法首先检索用户的位置,然后获取地点的 ID,最后获取这些地点的详细信息。
private void startPlaceFetchingTask(final String type) {
showProgress();
final long startTime = System.currentTimeMillis();
if (mResponses == null) {
mResponses = new ArrayList<>();
}
mResponses.clear();
Observable.fromCallable(this::getSynchronousLocation)
.subscribeOn(Schedulers.io())
.retryWhen(errors -> errors.flatMap(error -> {
long currentTime = System.currentTimeMillis();
if (error instanceof NullPointerException && (currentTime - startTime) < 30000) {
return Observable.timer(2, TimeUnit.SECONDS);
}
return Observable.error(error);
}))
.flatMap(location -> {
mLocation = location;
String locationString = location.latitude + "," + location.longitude;
return mapService.getPlaces(locationString, type)
.map(response -> response.getResults())
.flatMap(results -> Observable.fromIterable(results))
.flatMap(result -> mapService.getPlaceDetails(result.getPlaceId()));
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getObserver());
}
这是我用来检索用户当前位置的方法
private LatLng getSynchronousLocation() throws SecurityException, ExecutionException, InterruptedException, TimeoutException {
Location location = Tasks.await(mFusedLocationClient.getLastLocation(), 30, TimeUnit.SECONDS);
return new LatLng(location.getLatitude(), location.getLongitude());
}
并让观察者
private Observer<PlacesDetailsResponse> getObserver() {
return new Observer<PlacesDetailsResponse>() {
@Override
public void onSubscribe(Disposable d) {
addDisposable(d);
}
@Override
public void onNext(PlacesDetailsResponse placesDetailsResponse) {
addPlace(placesDetailsResponse);
}
@Override
public void onError(Throwable e) {
//handle error
hideProgress();
}
@Override
public void onComplete() {
//do stuff
hideProgress();
}
};
正如我之前所说,当应用程序打开并第一次单击搜索按钮时,所有这些都可以正常工作。如果再次单击该按钮,则只会调用 onComplete 并且不会在 onNext 上发出任何数据。如果有人能指出我在这里做错了什么,我将不胜感激。提前致谢。
编辑: 这是 addDisposable 方法,它将一次性用品添加到复合一次性用品并在 onDestroy 期间处置。
private void addDisposable(Disposable disposable) {
if (mDisposable == null) {
mDisposable = new CompositeDisposable();
}
mDisposable.add(disposable);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mDisposable != null && !mDisposable.isDisposed()) {
mDisposable.dispose();
}
}
解决方案
推荐阅读
- angular - TypeScript 编译中缺少 Module build failed ts。请通过 'files' 或 'include' 属性确保它在您的 tsconfig 中
- angularjs - 向 Web 服务发送错误的 URL
- reactjs - REACTJ + SlimPhP 上的 CORS 错误
- r - 比较 R 中的因子和字符串
- html - CSS内部链接与css文件无关?
- c# - 实体框架代码第一个数据库未与模型同步
- java - 检索 JSON 数据时字符串无法转换为 int 错误
- python - 如何拆分 Pandas DataFrameGroupBy
- selenium - 在 html 中检索当前的 chrome 打开页面而不保存它
- jquery - 使用 jquery 隐藏列表中的所有 li,但不隐藏具有类名“matter”的 li