Как я могу использовать переменную вне подписки - PullRequest
0 голосов
/ 22 сентября 2019

Я попытался зациклить вызов Api на основе размера массива и поместить результат в адаптер.Но я получаю нулевое значение, когда пытаюсь использовать результаты вызова API, потому что он находится за пределами подписки.как использовать переменную вне подписки?

Вот мой код

    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);
}

как получить значения фильмов вне подписки?

1 Ответ

1 голос
/ 23 сентября 2019

Ты не.Результат из потока является асинхронным, что означает, что он будет вызван через некоторое время, в то время как вы устанавливаете адаптер с данными синхронно.Кроме того, не используйте цикл при обработке потоков, используйте операторы Reactive, как показано ниже.Я не могу скомпилировать, чтобы проверить, работает ли он, но ниже приведен примерный правильный ответ на ваш вопрос.

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;
    }

PS Попробуйте ввести лямбда-выражения, чтобы сделать вашу жизнь проще, или даже лучше, Котлин !!!

...