我如何在订阅外部使用变量

How Do I Use Variable Outside Subscribe

我尝试根据数组大小循环调用 Api,并将结果放入适配器。但是当我尝试使用 api 调用的结果时我得到 null 因为它在订阅之外。如何在订阅外使用变量?

这是我的代码

    private void getMoviesData(final String lang) {
    favouriteMovies = databaseHelper.getAllFavouriteMovies();
    for (int i = 0; i < favouriteMovies.size(); i++) {
        api.getSingleMovie(favouriteMovies.get(i).getMovieId(),apiKey, lang)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(new Observer<SingleMovieResponse>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        progressBar.setVisibility(View.GONE);
                        Log.d(TAG, "Show Data Error!: " + e);
                    }

                    @Override
                    public void onNext(SingleMovieResponse singleMovieResponse) {

                        for (int i = 0; i < singleMovieResponse.getSpoken_languages().size(); i++ ) {
                            MoviesObject moviesObject = new MoviesObject();
                            moviesObject.setMovieId(singleMovieResponse.getId());
                            moviesObject.setTitle(singleMovieResponse.getTitle());
                            moviesObject.setPosterPath(singleMovieResponse.getPoster_path());
                            moviesObject.setOverview(singleMovieResponse.getOverview());
                            moviesObject.setReleaseDate(singleMovieResponse.getRelease_date());
                            moviesObject.setVoteAverage(singleMovieResponse.getVote_average());
                            if (singleMovieResponse.getOverview().equals("")) {
                                moviesObject.setOverview(Objects.requireNonNull(getActivity()).getResources().getString(R.string.no_overview_movie));
                            }
                            movies.add(moviesObject);
                        }

                    }
                });
    }
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    MovieAdapter movieAdapter = new MovieAdapter(movies,getActivity());
    recyclerView.setAdapter(movieAdapter);
    recyclerView.setHasFixedSize(true);
    progressBar.setVisibility(View.GONE);
    recyclerView.setVisibility(View.VISIBLE);
}

如何获取订阅外的电影值?

你不知道。流的结果是异步的,这意味着它会在一段时间后被调用,而您使用数据设置适配器是同步的。另外,在处理流时不要使用循环,使用响应式运算符,如下所示。我无法编译来测试它是否有效,但下面是你问题的大致正确答案。

private void getMoviesData(final String lang) {
        favouriteMovies = databaseHelper.getAllFavouriteMovies();
        Observable.fromIterable(favouriteMovies) // Creates a stream of Favourite Movies
                .flatMap(new Function<FavouriteMovie, ObservableSource<?>>() { // Makes a request for each FavouriteMovie 
                    @Override
                    public ObservableSource<?> apply(FavouriteMovie favouriteMovie) throws Exception {
                        return api.getSingleMovie(favouriteMovie.getMovieId(), apiKey, lang);
                    }
                })
                .map(new Function<SingleMovieResponse, MoviesObject>() { // Maps the response to the wanted object
                    @Override
                    public MoviesObject apply(SingleMovieResponse singleMovieResponse) throws Exception {
                        return map(singleMovieResponse);
                    }
                })
                .toList() // Merges each item of the Observable stream into a Single stream as List<Object>
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(new SingleObserver<List<MoviesObject>>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onSuccess(List<MoviesObject> moviesObjects) {
                        progressBar.setVisibility(View.GONE);
                        recyclerView.setVisibility(View.VISIBLE);
                        movieAdapter.setList(moviesObjects); // Create this method in the adapter to update list
                        movieAdapter.notifyDataSetChanged();
                    }

                    @Override
                    public void onError(Throwable e) {
                        progressBar.setVisibility(View.GONE);
                        Log.d(TAG, "Show Data Error!: " + e);
                    }
                });

        movieAdapter = new MovieAdapter(movies,getActivity()); // MovieAdapter should be a class field
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        recyclerView.setHasFixedSize(true);
        recyclerView.setAdapter(movieAdapter);
    }

    private MoviesObject map(SingleMovieResponse singleMovieResponse) {
        MoviesObject moviesObject = new MoviesObject();
        moviesObject.setMovieId(singleMovieResponse.getId());
        moviesObject.setTitle(singleMovieResponse.getTitle());
        moviesObject.setPosterPath(singleMovieResponse.getPoster_path());
        moviesObject.setOverview(singleMovieResponse.getOverview());
        moviesObject.setReleaseDate(singleMovieResponse.getRelease_date());
        moviesObject.setVoteAverage(singleMovieResponse.getVote_average());
        if (singleMovieResponse.getOverview().equals("")) {
            moviesObject.setOverview(Objects.requireNonNull(getActivity()).getResources().getString(R.string.no_overview_movie));
        }
        return moviesObject;
    }

P.S。尝试引入 lambda 表达式让你的生活更轻松,甚至更好的 Kotlin!!!