我正在尝试查询API以获取JSON响应并将响应存储在ArrayList中。
此ArrayList稍后将用于设置RecyclerView。
如果我从OkHttp登录 OnResponse()方法,我会收到回复。但是当我通过 OkhttpHandler 中的返回将我的片段中的响应作为字符串接收时,则字符串值将被接收为null
这是代码
OkHttpHelper.Java
package com.execube.genesis.utils;
import android.util.Log;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
/**
* Created by Prateek Phoenix on 4/24/2016.
*/
public class OkHttpHandler {
private String queryUrl;
private String jsonData;
private static final String TAG = "CustomTAG1";
public OkHttpHandler(String Url) {
this.queryUrl = Url;
}
public String fetchData() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(queryUrl)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.v(TAG, "Exception: ", e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.v(TAG, response.body().string());
if (response.isSuccessful()) {
jsonData = response.body().string();
}
}
});
return jsonData; //Even this is null when I check via Debugger
}
}
PopularMoviesFragment.java
package com.execube.genesis.views;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import com.execube.genesis.R;
import com.execube.genesis.model.Movie;
import com.execube.genesis.utils.API;
import com.execube.genesis.utils.OkHttpHandler;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
/**
* Created by Prateek Phoenix on 4/24/2016.
*/
public class PopularMoviesFragment extends Fragment {
private static final String TAG = "CustomTAG";
private ArrayList<Movie> mMovies;
private String jsonResponse;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
mMovies=new ArrayList<>();
String url= API.BASE_URL+API.API_KEY+API.SORT_POPULARITY;
OkHttpHandler handler= new OkHttpHandler(url);
jsonResponse=handler.fetchData();
try {
mMovies= parseItems(jsonResponse);
} catch (JSONException e) {
Log.v(TAG,"Exception caught: ",e);
}
super.onCreate(savedInstanceState);
}
private ArrayList<Movie> parseItems( String jsonResponse) throws JSONException{
JSONObject jsonData= new JSONObject(jsonResponse);
JSONArray moviesJSONArray= jsonData.getJSONArray("results");
ArrayList<Movie> Movies= new ArrayList<>();
for (int i = 0; i <moviesJSONArray.length() ; i++) {
Movie movie= new Movie();
JSONObject movieJson= moviesJSONArray.getJSONObject(i);
movie.setId(movieJson.getInt("id"));
Log.v(TAG,"TITLE IS "+movieJson.getString("title"));
movie.setOriginalTitle(movieJson.getString("original_title"));
movie.setOverview(movieJson.getString("overview"));
movie.setPosterPath(movieJson.getString("poster_path"));
movie.setVoteAverage((float) movieJson.getDouble("vote_average"));
movie.setTitle(movieJson.getString("title"));
Movies.add(movie);
}
return Movies;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view= inflater.inflate(R.layout.fragment_popular_movies,container,false);
return view;
}
}
用于构建网址的API.java
package com.execube.genesis.utils;
/**
* Created by Prateek Phoenix on 4/24/2016.
*/
public class API {
public static String BASE_URL = "http://api.themoviedb.org/3/discover/movie?";
public static String MOVIE_BASE_URL = "http://api.themoviedb.org/3/movie/";
public static String API_KEY = "api_key=a98debe57ccd9b42fe6b99b9014c80e3";
public static String SORT_POPULARITY = "&sort_by=popularity.desc";
public static String SORT_R_RATED = "&certification_country=US&certification=R&sort_by=vote_average.desc&vote_count.gte=250";
public static String IMAGE_URL = "http://image.tmdb.org/t/p/";
public static String IMAGE_SIZE_185 = "w500";
}
答案 0 :(得分:0)
Call#enqueue
是OkHttp的异步API。这意味着请求将在后台线程上处理,并且调用线程将继续使用OR运行而不运行回调。
要使用数据,您需要使用某种形式的Future
(Guava的ListenableFuture或RxJava可能有效)来响应最终数据的可用性或使用<{1}}代替Call#execute()
以同步方式进行调用。
答案 1 :(得分:0)
问题是,在网络操作完成并在其中放入内容之前,您正在访问变量jsonData。 哪种情况不太可能发生。
使用类似事件总线的东西(我喜欢绿色机器人),并在jsonData有东西时发布一个事件,紧跟在行jsonData = response.body().string();
在您的UI片段中收听此事件,并在收到此事件后填充数据。
然后,继续显示进度对话框/ UI。
通过这种方式,您的代码将保持异步,您也可以完成此操作