java - 循环 AsyncTask 以获取 JSON 并将其作为对象存储在同一列表中

标签 java android json object android-asynctask

我想读取并存储来自 this api Link 的所有 JSON 值以 get request "Mini" 为例(这实际上是一个用户输入变量),最后一个数字是您正在查看的页面。每页最多可包含 50 个结果。 same link is also in XML格式(我必须读取和存储为 JSON,这是为了更容易理解)

在这个例子中有 8 个页面,共有 359 个结果。我需要遍历所有页面并将所有 JSON 值添加到同一对象列表。

我有阅读一页的代码。我不知道如何让它遍历所有页面并添加到相同的对象列表。

在 acitivty.java onCreate 中,我调用了 AsyncTask。

String userSearchRequest = search_activity_data.getString("userSearchRequest");
int page = 0;
String spidy_iTN_url = "http://www.gw2spidy.com/api/v0.9/json/item-search/" + userSearchRequest + "/" + page;

itemsByInput_AsyncTask itemsByInput_AsyncTask = new itemsByInput_AsyncTask();
itemsByInput_AsyncTask.setItemListToListings(this);
itemsByInput_AsyncTask.execute(spidy_iTN_url);

这是我的 AsyncTask 类,名为 itemsByInput_AsyncTask.java

import constructors.itemResults_api_constr;
import constructors.itemRoot_api_constr;

public class itemsByInput_AsyncTask extends AsyncTask<String, Void, JSONObject> {

        JSONObject Jo_result;
        private itemListToListings itemListToListings;

     public void setItemListToListings (itemListToListings itemListToListings) {
        this.itemListToListings = itemListToListings;
    }

    @Override
    protected JSONObject doInBackground(String... params) {
        return spidyHttpGetRequest(params[0]);
    }

    public JSONObject spidyHttpGetRequest(String URL){
        try {
            HttpGet get = new HttpGet(URL);
            HttpClient client = new DefaultHttpClient();
            HttpResponse response = client.execute(get);
            HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString(entity);
            Jo_result = new JSONObject(result);

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return Jo_result;
    }

    @Override
    protected void onPostExecute(JSONObject jsonObject) {
        super.onPostExecute(jsonObject);
        this.itemListToListings.itemListToListings(JoToJO_constructor(jsonObject));
    }


    public itemRoot_api_constr JoToJO_constructor(JSONObject Jo_result) {
        itemRoot_api_constr spidy_iTN_rootO = new itemRoot_api_constr();

        try {
            spidy_iTN_rootO.setCount(Jo_result.getInt("count"));
            spidy_iTN_rootO.setPage(Jo_result.getInt("page"));
            spidy_iTN_rootO.setLast_page(Jo_result.getInt("last_page"));
            spidy_iTN_rootO.setTotal(Jo_result.getInt("total"));
            JSONArray list = new JSONArray(Jo_result.getString("results"));

            for (int i = 0; i < spidy_iTN_rootO.getCount(); i++) {
                JSONObject resultsObject = list.getJSONObject(i);
                itemResults_api_constr spidy_iTN_resultsO = new itemResults_api_constr();

                spidy_iTN_resultsO.setData_id(resultsObject
                        .getInt("data_id"));
                spidy_iTN_resultsO.setName(resultsObject
                        .getString("name"));
                spidy_iTN_resultsO.setRarity(resultsObject
                        .getInt("rarity"));
                spidy_iTN_resultsO.setRestriction_level(resultsObject
                        .getInt("restriction_level"));
                spidy_iTN_resultsO.setImg(resultsObject
                        .getString("img"));
                spidy_iTN_resultsO.setType_id(resultsObject
                        .getInt("type_id"));
                spidy_iTN_resultsO.setSub_type_id(resultsObject
                        .getInt("sub_type_id"));
                spidy_iTN_resultsO.setPrice_last_changed(resultsObject
                        .getString("price_last_changed"));
                spidy_iTN_resultsO.setMax_offer_unit_price(resultsObject
                        .getInt("max_offer_unit_price"));
                spidy_iTN_resultsO.setMin_sale_unit_price(resultsObject
                        .getInt("min_sale_unit_price"));
                spidy_iTN_resultsO.setOffer_availability(resultsObject
                        .getInt("offer_availability"));
                spidy_iTN_resultsO.setSale_availability(resultsObject
                        .getInt("sale_availability"));
                spidy_iTN_resultsO.setSale_price_change_last_hour(resultsObject
                        .getInt("sale_price_change_last_hour"));
                spidy_iTN_resultsO.setOffer_price_change_last_hour(resultsObject
                        .getInt("offer_price_change_last_hour"));
                spidy_iTN_rootO.addObject(spidy_iTN_resultsO);
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }

        return spidy_iTN_rootO;
    }

    public interface itemListToListings {
        public void itemListToListings(itemRoot_api_constr resultClass);
    }


}

最后,在我的 activity.java 中,我可以在 itemListToListings() 方法中使用我的对象。

我怎样才能使这个循环遍历所有页面(last_page 属性)并将所有 JSON 值作为对象添加到同一列表中。

编辑:我的 itemListToListings 函数在我的 Activity 中。

public void itemListToListings(final itemRoot_api_constr spidy_iTN_construct) {
            ArrayList<listItemWidgets_constr> image_details = getListData(spidy_iTN_construct);
            final ListView lv1 = (ListView) findViewById(R.id.listView);
            lv1.setAdapter(new itemListAdapter(this, image_details));
            lv1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> a, View v, int position, long id) {
                    //listItemWidgets_constr newsData = (listItemWidgets_constr) lv1.getItemAtPosition(position);
                    Toast.makeText(resultsActivity.this, "Selected :" + spidy_iTN_construct.results(position).name, Toast.LENGTH_LONG).show();

                    Intent i = new Intent(resultsActivity.this, listingsActivity.class);
                    i.putExtra("itemId", spidy_iTN_construct.results(position).data_id);
                    startActivity(i);
                }
            });
        }

编辑 3:错误日志

05-01 07:17:39.828    3620-3620/com.example.krijn.gw2TP_androidMobile E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.example.krijn.gw2TP_androidMobile, PID: 3620
    java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.krijn.gw2TP_androidMobile.AsyncTasks.itemsByInput_AsyncTask$itemListToListings.itemListToListings(com.example.krijn.gw2TP_androidMobile.constructors.itemRoot_api_constr)' on a null object reference
            at com.example.krijn.gw2TP_androidMobile.AsyncTasks.itemsByInput_AsyncTask.onProgressUpdate(itemsByInput_AsyncTask.java:88)
            at com.example.krijn.gw2TP_androidMobile.AsyncTasks.itemsByInput_AsyncTask.onProgressUpdate(itemsByInput_AsyncTask.java:27)

在我在 Logcat 中收到此错误后,我仍然在 doInBackground

中看到日志更新为以下内容
for (int n = 1; n < nPage; n++){
            Log.i("gw2Log", "n: " + n);
            publishProgress(JoToJO_constructor(spidyHttpGetRequest(makeUrl(n))));
        }

完成循环后应用程序崩溃。

最佳答案

我认为您想根据从第一页获得的 last_page 属性进行链式调用。我会做这样的事情,在每次完成请求时,UI 都会在 onProgressUpdate

上更新
public class itemsByInput_AsyncTask extends AsyncTask<Void, itemRoot_api_constr, Void> {

 JSONObject Jo_result;
 private itemListToListings itemListToListings;
 String userSearchRequest;

 public itemsByInput_AsyncTask(String userSearchRequest){
  this.userSearchRequest = userSearchRequest;
 } 

 private String makeUrl(int page){
    return "http://www.gw2spidy.com/api/v0.9/json/item-search/" + 
           this.userSearchRequest + "/" + page;
 }

 @Override
 protected Void doInBackground(Void... params) {
    itemRoot_api_constr iac;

    iac = JoToJO_constructor(spidyHttpGetRequest(makeUrl(0)));
    nPage = iac.getLast_page();
    publishProgress(iac);

    for (int n = 1; n<nPage; n++){
         publishProgress(spidyHttpGetRequest(makeUrl(n)));
    }
    return null;
 }

 @Override
 protected void onProgressUpdate(itemRoot_api_constr... iacs) {
       super.onProgressUpdate(iacs);
       // assuming method itemListToListings updates UI
       // if it doesn't then publishProgress and onProgressUpdate are not needed 
       // and itemListToListings can be done in doInBackground
       this.itemListToListings.itemListToListings(iacs[0]);
 }

  @Override
  protected Void onPostExecute(Void void) {
    super.onPostExecute(void);   
    // unused    
 }
}

还有: 适配器、 View 和相关的点击监听器应该被启动一次。您应该将 itemListToListings 中的所有变量作为您的 Activity 字段移动,这样每次调用此回调时,都不需要再次启动它们。

  ListView lv1;
  ArrayList<listItemWidgets_constr> image_details = new ArrayList<>();
  itemListAdapter adapter; 

  void onCreate(){
    ...
    lv1 = (ListView) findViewById(R.id.listView);
    adapter = new itemListAdapter(this, image_details);
    lv1.setOnItemClickListener(...);
  }

  public void itemListToListings(final itemRoot_api_constr spidy_iTN_construct) {
        image_details.clear();
        image_details.addAll(getListData(spidy_iTN_construct));
        adapter.notifyDataSetChanged();      
    }

关于java - 循环 AsyncTask 以获取 JSON 并将其作为对象存储在同一列表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29972811/

相关文章:

java - 在 clojure 中取消引用 java 方法

android - 在 Android 中启用禁用蓝牙

android - 当我在 Gridview 中的 View 项目上放置图像时如何修复 gridview 项目大小(宽度和高度)

java - FLAG_NOT_FOCUSABLE Activity

php - 从对 PHP 脚本的 ajax 调用获取 JSON 响应

java - 如何从 JSON 文件中删除项目?

java - PropertyPage - 通过“确定”按钮进行控制

java - 使用动态字段反序列化嵌套 XML

ruby-on-rails - 如何在 Rails 中构建由多个模型组成的 JSON 响应

java - 扩展 GUI 表单时,JButton 无法启用