拜托,我做错了什么?我使用volley从Moviedb api获取数据。第一种方法调用应该是获取流行电影并将它们存储在ArrayListA(popularMoviesList)中,第二种调用应该是获取最高评级的电影并存储在另一个ArrayListB(topRatedMoviesList)中。但是当我调用方法并传递它们各自的URL时,ArrayListA包含流行和评级最高的电影的数据,而ArrayListB是空的。
这是具有方法
的类import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
public class MovieDataSource {
private final static String MOVIE_ID="id";
private final static String MOVIE_RATING = "vote_average";
private final static String MOVIE_TITLE = "original_title";
private final static String MOVIE_POSTERPATH = "poster_path";
private final static String MOVIE_DESCRIPTION = "overview";
private final static String MOVIE_RELEASEDATE = "release_date";
private final static String API_KEY = "";// paste api key inside the double quote
private RequestQueue mRequestQueue = VolleySingleton.getmInstance().getmRequestQueue();
public ArrayList<Movie> movieArrayList(String URL){
final ArrayList<Movie> listOfMovies = new ArrayList<>();
String url= URL + API_KEY;
JsonObjectRequest jsonObjectRequest= new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
int movieId;
double movieRating;
String movieTitle, imagePath, movieDescription,movieReleaseDate;
Log.i("successful", response.toString());
try {
JSONArray results = response.getJSONArray("results"); // get json array from the object
JSONObject object; // to get objects from result array
Movie movie;
for(int i=0; i<results.length(); i++) {
object = results.getJSONObject(i);// get objects in the array based on their position/index in the array
//get values from the objects that will be used to populate instantiated movies
movieId = object.getInt(MOVIE_ID);
movieRating = object.getDouble(MOVIE_RATING);
movieTitle = object.optString(MOVIE_TITLE);
imagePath = object.optString(MOVIE_POSTERPATH);
movieDescription = object.optString(MOVIE_DESCRIPTION);
movieReleaseDate = object.optString(MOVIE_RELEASEDATE);
//// for every element in the array( index i), create a new movie
movie = new Movie(movieId,movieRating,movieTitle,imagePath,movieDescription, movieReleaseDate);
// add each movie created to the arrayList
listOfMovies.add(movie);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
Log.i("error", "onErrorResponse: something went wrong ");
}
});
mRequestQueue.add(jsonObjectRequest);
return listOfMovies;
}
在MainActivity中调用该方法
MovieDataSource movieDataSource = new MovieDataSource();
final ArrayList<Movie>popularMoviesList = movieDataSource.movieArrayList(popularMoviesUrl)
final ArrayList<Movie> topRatedMoviesList = movieDataSource1.movieArrayList(topRatedMovieUrl);
问题是:popularMovieList包含自己的预期数据和数据,意味着topRatedMoviesList。没有返回topRatedMoviesList。什么可能导致这种行为?
答案 0 :(得分:0)
这是因为您的请求以异步方式运行。因此,您使用相同的movieDataSource运行2个请求。当两个请求完成后,您将填充相同的movieDataSource.listOfMovies,然后返回。尝试为MainActivity中的每个请求创建单独的MovieDataSource。
MovieDataSource movieDataSource1 = new MovieDataSource();
final ArrayList<Movie>popularMoviesList = movieDataSource1.movieArrayList(popularMoviesUrl)
MovieDataSource movieDataSource2 = new MovieDataSource();
final ArrayList<Movie> topRatedMoviesList = movieDataSource2.movieArrayList(topRatedMovieUrl);
但说实话,这段代码对我来说错了。您立即返回空数组,然后在请求完成时填充它,但是您的MainActivity如何知道它是否准备就绪?我将从MainActivity传递完成回调,当请求完成时,可以使用接收数组作为参数调用。问我是否需要其他帮助。
答案 1 :(得分:0)
您应该使用回调(接口)而不是使用返回值。
您的代码将执行什么操作(完全错误):
它会创建一个列表
将在单独的任务(See AsyncTask)中调用api,因此您的代码不会等待让其响应。
它会返回空白列表。
现在,当您的回复出现时,它与此无关。
解决方案:
如果您了解接口,那么就可以使用它。接口用于在任务完成时调用某些方法。
在您的代码中实现api的正确方法如下
<GridLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:columnCount="4"
android:rowCount="6"
<!-- android:onClick="dropIn" -->
android:layout_alignParentEnd="true"
android:id="@+id/gridLayout">
您的 public static final int REQUEST_CODE_POPULAR = 1;
public static final int REQUEST_CODE_TOP_RATED = 2;
ArrayList<Movie> popularMoviesList = new ArrayList<>();
ArrayList<Movie> topRatedMoviesList = new ArrayList<>();
private void setData() {
String popularMoviesUrl = "yourUrl";
String topRatedMovieUrl = "yourUrl";
MovieDataSource object = new MovieDataSource(); // use only one object
OnResponseListener<ArrayList<Movie>> listener = new OnResponseListener<ArrayList<Movie>>() {
@Override
public void onSuccess(int tag, ArrayList<Movie> object) {
if (tag == REQUEST_CODE_POPULAR) {
popularMoviesList = object;
// TODO: 5/27/2018 use this list further
} else if (tag == REQUEST_CODE_TOP_RATED) {
topRatedMoviesList = object;
// TODO: 5/27/2018 use this list further
}
}
@Override
public void onError(Exception e) {
// todo handle error
}
};
object.movieArrayList(popularMoviesUrl, REQUEST_CODE_POPULAR, listener);
object.movieArrayList(topRatedMovieUrl, REQUEST_CODE_TOP_RATED, listener);
}
课程。
MovieDataSource