【发布时间】:2015-07-03 13:38:52
【问题描述】:
我想连接到一个 Api,它根据我作为 GET 请求输入的内容返回 JSON 值。此 JSON 结构始终完全相同,只是这些属性的值不同。然后将所有这些 JSON 值构造成一个对象列表,并从那里进一步在应用程序中使用用户。
在帮助下,我现在有了一个工作代码,可以连接并读取 JSON 和 HttpEntity 的值,并将这些值存储在 new JSONObject 中。该对象被发送到另一个函数,在该函数中该对象被剥离,然后将constructed 转换为Object list 以供以后在应用程序中使用。
此代码工作。除了此 Api 链接仅显示 50 个结果,具体取决于输入为 GET 请求的内容。当结果超过 50 个时,将创建一个新页面,可以通过 url 末尾的数字访问该页面。所有这些可能存在的页面(不必作为用户搜索请求)也必须添加到对象列表中。
问题:如何使用新的 url 遍历扩展的 AsyncTask 类以从中获取 JSON 数据?
我再次注意到,此代码适用于单个页面,但我不知道如何遍历所有现有页面并将它们添加到同一个对象列表中。
我们从activity.java开始
String userSearchRequest = search_activity_data.getString("userSearchRequest");
String URL = "http://www.gw2spidy.com/api/v0.9/json/item-search/" + userSearchRequest + "/";
// example api url:
//http://www.gw2spidy.com/api/v0.9/json/item-search/Iron/0"
//The last number is the page you are viewing, every 50 results a new page is created. With 51 results there will be a page 0 and 1 to access.
AsyncFetch AsyncFetch = new AsyncFetch(this);
AsyncFetch.setOnResponse(this);
AsyncFetch.execute(URL);
从这里将 URL 传递给 AsyncFetch 类,以将 doInBackground 作为参数。
public class AsyncFetch extends AsyncTask<String, Void, JSONObject> {
public AsyncFetch(Context context) {
this.context = context;
}
private Context context;
private JSONObject jsonObject;
private onResponse onResponse;
public void setOnResponse (onResponse onResponse) {
this.onResponse = onResponse;
}
@Override
protected JSONObject doInBackground(String... params ) { //Incompatible return type
// TODO Auto-generated method stub
try {
HttpGet get = new HttpGet(params[0]);
HttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(get);
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity);
jsonObject = new JSONObject(result);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return jsonObject;
}
@Override
protected void onPostExecute(JSONObject result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
this.onResponse.onResponse(result);
}
public interface onResponse {
public void onResponse(JSONObject object);
}
}
在AsyncFetch 类中的onPostExecute 中,然后将对象发送回activity.java
public void onResponse(JSONObject object) {
Log.i("gw2Log", object.toString());
apiRootObject resultClass = new apiRootObject();
try {
resultClass.setCount(object.getInt("count"));
resultClass.setPage(object.getInt("page"));
resultClass.setLast_page(object.getInt("last_page"));
resultClass.setTotal(object.getInt("total"));
JSONArray list = new JSONArray(object.getString("results"));
for (int i = 0; i < resultClass.getCount(); i++) {
JSONObject resultsObject = list.getJSONObject(i);
apiResults temp = new apiResults();
temp.setData_id(resultsObject
.getInt("data_id"));
temp.setName(resultsObject
.getString("name"));
temp.setRarity(resultsObject
.getInt("rarity"));
temp.setRestriction_level(resultsObject
.getInt("restriction_level"));
temp.setImg(resultsObject
.getString("img"));
temp.setType_id(resultsObject
.getInt("type_id"));
temp.setSub_type_id(resultsObject
.getInt("sub_type_id"));
temp.setPrice_last_changed(resultsObject
.getString("price_last_changed"));
temp.setMax_offer_unit_price(resultsObject
.getInt("max_offer_unit_price"));
temp.setMin_sale_unit_price(resultsObject
.getInt("min_sale_unit_price"));
temp.setOffer_availability(resultsObject
.getInt("offer_availability"));
temp.setSale_availability(resultsObject
.getInt("sale_availability"));
temp.setSale_price_change_last_hour(resultsObject
.getInt("sale_price_change_last_hour"));
temp.setOffer_price_change_last_hour(resultsObject
.getInt("offer_price_change_last_hour"));
resultClass.addObject(temp);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i = 0; i < resultClass.count; i++) {
Log.i("gw2Log", resultClass.getObject(i).name);
}
}
现在我可以从这里访问resultClass 列表并遍历所有对象并显示它们的属性和值。
我怎样才能使这适用于具有完全相同 JSON 结构的多个页面?
编辑:我有这个在 c# 中工作的代码。这是我的完全相同的项目,但现在在 Android java 中。所以目标是完全一样的,但我不能让它工作
public static RootObject objFromApi_idToName(string spidyApiUrl, int page){
RootObject rootObject = null;
RootObject tempRootObject = null;
do{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(spidyApiUrl + "/" + page);
WebResponse response = request.GetResponse();
using (Stream responseStream = response.GetResponseStream()){
StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
var jsonReader = new JsonTextReader(reader);
var serializer = new JsonSerializer();
tempRootObject = serializer.Deserialize<RootObject>(jsonReader);
if (rootObject == null){
rootObject = tempRootObject;
}
else{
rootObject.results.AddRange(tempRootObject.results);
rootObject.count += tempRootObject.count;
}
}
page++;
}
while (tempRootObject != null && tempRootObject.last_page != tempRootObject.page);
return rootObject;
}
【问题讨论】:
-
尝试将
AsyncFetch.execute(URL);改为AsyncFetch.execute(URL+YourPageNumber);(例如:AsyncFetch.execute(URL+5);加载第5页) -
@Rami 我需要自动循环浏览所有页面,而不是手动执行。
标签: java android json list object