我使用Volley获取一些JSON数据来填充RecyclerView列表。初始JSON文件返回一些信息,如:
如果我使用"服务器URL / server / id"请求新的JSON;然后我可以获得一些关于要在视图上显示的服务器/项目的额外信息,如:
我想在我的RecyclerView列表中显示每个项目的两组信息,例如:
但是我需要每个服务器的id来使用辅助JSON文件获取额外的信息。
为了说明我需要得到:
但我得到了:
我将以下代码放在一起,以获取每个项目的额外信息,以便在解析主JSON文件时请求额外数据但是我得到完全相同的"地址","输入& #34;,"味道"对于每一件物品:
Parser Class:
public class NovaParser extends Activity{
public static final String ID = "id";
public static final String NAME = "name";
public static final String STATUS = "status";
public static final String FLAVOR = "flavor";
public static final String NETID = "netid";
public static final String ADDR = "addr";
public static final String HOST = "host";
public String authToken;
public String novaURL;
public SharedPreferences shPref;
public ArrayList<HashMap<String, String>> flavorList;
public static NovaParser parser = null;
public static NovaParser shared(){
if (parser == null){
parser = new NovaParser();
}
return parser ;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void setFlavorList(ArrayList<HashMap<String, String>> flavorList) {
this.flavorList = flavorList;
}
public ArrayList<HashMap<String, String>> getFlavorList(){
return flavorList;
}
public static ArrayList<HashMap<String, String>> parseJSON(String novaJSON){
ArrayList<HashMap<String, String>> jsonList = new ArrayList<HashMap<String, String>>();
ArrayList<HashMap<String, String>> tempList = new ArrayList<HashMap<String, String>>();
try {
NovaInstances novaInstance = new NovaInstances();
JSONObject nova = new JSONObject(novaJSON);
JSONArray servers = nova.getJSONArray("servers");
for (int i = 0; i < servers.length(); i++) {
JSONObject objsrv = servers.getJSONObject(i);
novaInstance.setName(objsrv.getString("name"));
novaInstance.setId(objsrv.getString("id"));
novaInstance.setStatus(objsrv.getString("OS-EXT-STS:vm_state"));
novaInstance.setHost(objsrv.getString("OS-EXT-SRV-ATTR:host"));
String id = novaInstance.getId();
String instanceDetail = NovaJSON.shared().receiveDetail(id);
if (instanceDetail != null) {
novaInstance.setFlavor(parseFlavor(instanceDetail));
}
String netDetail = NovaJSON.shared().receiveIP(id);
if (netDetail != null) {
tempList = parseNet(netDetail);
}
for (int j = 0; j < tempList.size(); j++) {
novaInstance.setNetid(tempList.get(j).get(NETID));
novaInstance.setAddr(tempList.get(j).get(ADDR));
}
HashMap<String, String> map = new HashMap<String, String>();
map.put(NAME, novaInstance.getName());
map.put(ID, novaInstance.getId());
map.put(STATUS, novaInstance.getStatus());
map.put(FLAVOR, novaInstance.getFlavor());
map.put(HOST, novaInstance.getHost());
map.put(NETID, novaInstance.getNetid());
map.put(ADDR, novaInstance.getAddr());
jsonList.add(map);
}
} catch (JSONException e) {
Log.d("ErrorInitJSON", e.toString());
e.printStackTrace();
}
Collections.sort(jsonList, new Comparator<HashMap<String, String>>() {
@Override
public int compare(HashMap<String, String> lhs, HashMap<String, String> rhs) {
return (lhs.get("name")).compareToIgnoreCase(rhs.get("name"));
}
});
return jsonList;
}
public static String parseFlavor(String instanceDetail){
ArrayList<HashMap<String, String>> flavorList = NovaParser.shared().getFlavorList();
String temp = null;
JSONObject novaDetail = null;
try {
novaDetail = new JSONObject(instanceDetail);
JSONObject server = novaDetail.getJSONObject("server");
JSONObject flavor = server.getJSONObject("flavor");
if (flavorList !=null){
temp = flavor.getString("id");
for (Map<String,String> map : flavorList) {
if (map.containsValue(temp)) {
temp = map.get(NAME);
}
}
}
/*JSONObject addresses = server.getJSONObject("addresses");
Iterator<String> keys=addresses.keys();
while(keys.hasNext())
{
String key=keys.next();
String value=addresses.getString(key);
novaInstance.setNet(value);
}
JSONObject security_groups = server.getJSONObject("security_groups");*/
} catch (JSONException e) {
e.printStackTrace();
}
return temp;
}
public static ArrayList<HashMap<String, String>> parseNet(String netDetail){
ArrayList<HashMap<String, String>> netList = new ArrayList<HashMap<String, String>>();
String netId = null, addr = null;
JSONObject net = null;
try {
net = new JSONObject(netDetail);
JSONObject addresses = net.getJSONObject("addresses");
Iterator<String> keys=addresses.keys();
while(keys.hasNext())
{
String key=keys.next();
String value=addresses.getString(key);
netId = key;
JSONArray network = addresses.getJSONArray(key);
for (int i = 0; i < network.length(); i++) {
JSONObject objnet = network.getJSONObject(i);
addr = objnet.getString("addr");
HashMap<String, String> map = new HashMap<String, String>();
map.put(NETID, netId);
map.put(ADDR, addr);
netList.add(map);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return netList;
}
}
Volley类获取JSON数据:
public class NovaJSON extends Activity {
String novaJSON;
String nova;
String auth;
String novaJSONdetail;
String novaJSONip;
String id;
RequestQueue queue = null;
public static NovaJSON parser = null;
public static NovaJSON shared(){
if (parser == null){
parser = new NovaJSON();
}
return parser ;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getNovaJSON() {
return novaJSON;
}
public void setNovaJSON(String novaJSON) {
this.novaJSON = novaJSON;
}
public String getNova() {
return nova;
}
public void setNova(String nova) {
this.nova = nova;
}
public String getAuth() {
return auth;
}
public void setAuth(String auth) {
this.auth = auth;
}
public String getNovaJSONdetail() {
return novaJSONdetail;
}
public void setNovaJSONdetail(String novaJSONdetail) {
this.novaJSONdetail = novaJSONdetail;
}
public String getNovaJSONip() {
return novaJSONip;
}
public void setNovaJSONip(String novaJSONip) {
this.novaJSONip = novaJSONip;
}
public String receiveData (String novaURL, String authToken){
setNova(novaURL);
setAuth(authToken);
getJSON();
getNovaJSON();
return novaJSON;
}
public String receiveDetail (String id){
setId(id);
getJSONdetail();
getNovaJSONdetail();
return novaJSONdetail;
}
public String receiveIP (String id){
setId(id);
getJSONip();
getNovaJSONip();
return novaJSONip;
}
public void getJSON() {
final String authToken = getAuth();
String novaURL = getNova();
novaURL = novaURL+"/servers/detail";
JsonObjectRequest getRequest = new JsonObjectRequest(Request.Method.GET, novaURL, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.d("Nova on Response", response.toString());
setNovaJSON(response.toString());
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("Nova on Error", "Error: " + error.getMessage());
setNovaJSON(error.toString());
}
}
) {
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("X-Auth-Token", authToken);
params.put("User-Agent", "stackerz");
params.put("Accept", "application/json");
params.put("Content-Type", "application/json; charset=utf-8");
return params;
}
};
queue = VolleySingleton.getInstance(this).getRequestQueue();
//VolleySingleton.getInstance(this).addToRequestQueue(getRequest);
queue.add(getRequest);
}
public void getJSONdetail() {
final String authToken = getAuth();
String novaURL = getNova();
novaURL = novaURL+"/servers/"+id;
JsonObjectRequest getRequest = new JsonObjectRequest(Request.Method.GET, novaURL, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.d("Nova on Response", response.toString());
setNovaJSONdetail(response.toString());
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("Nova on Error", "Error: " + error.getMessage());
setNovaJSONdetail(error.toString());
}
}
) {
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("X-Auth-Token", authToken);
params.put("User-Agent", "stackerz");
params.put("Accept", "application/json");
params.put("Content-Type", "application/json; charset=utf-8");
return params;
}
};
queue = VolleySingleton.getInstance(this).getRequestQueue();
//VolleySingleton.getInstance(this).addToRequestQueue(getRequest);
queue.add(getRequest);
}
public void getJSONip() {
final String authToken = getAuth();
String novaURL = getNova();
novaURL = novaURL+"/servers/"+id+"/ips";
JsonObjectRequest getRequest = new JsonObjectRequest(Request.Method.GET, novaURL, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.d("Nova on Response", response.toString());
setNovaJSONip(response.toString());
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("Nova on Error", "Error: " + error.getMessage());
setNovaJSONip(error.toString());
}
}
) {
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("X-Auth-Token", authToken);
params.put("User-Agent", "stackerz");
params.put("Accept", "application/json");
params.put("Content-Type", "application/json; charset=utf-8");
return params;
}
};
queue = VolleySingleton.getInstance(this).getRequestQueue();
//VolleySingleton.getInstance(this).addToRequestQueue(getRequest);
queue.add(getRequest);
}
}
经过一些调试后,我发现Volley在以下方法上太慢了:
public String receiveDetail (String id){
setId(id);
getJSONdetail();
getNovaJSONdetail();
return novaJSONdetail;
}
public String receiveIP (String id){
setId(id);
getJSONip();
getNovaJSONip();
return novaJSONip;
}
getJSONxxx()工作正常并使用每个单项的JSON数据设置novaJSONxxx字符串,但getter getNovaxxx()始终返回第一个项的值。对于Volley来说,吸气得太快了。使用AsyncTask,当数据准备就绪时可以运行onPostExecute(),但是Volley没有这个选项。
有没有办法让它工作或实现替代方案,以便每个JSON数据都返回到正确的项目?
答案 0 :(得分:0)
我通过完全倾倒Volley并转向Retrofit解决了我的问题。我将所有调用设置为同步/阻塞,使用try / catches计算出异常/错误,并在OkHTTP客户端上设置短暂超时。现在它按照我的意愿工作。