我如何在订阅外部使用变量
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!!!
我尝试根据数组大小循环调用 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!!!