RxJava Observable onNext不第二次调用

时间:2018-08-03 22:17:03

标签: android rx-java retrofit google-places-api

我对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方法,它将一次性对象添加到Composite一次性对象中,并在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();
    }
}

0 个答案:

没有答案