2014-07-02 76 views
0

Im在AsyncTask中通過JSON中的數據填充項目對象並將其添加到ArrayList。我在活動的onCreate方法中執行JSON類之後,我打印出ArrayList的大小爲0.在JSON類中的數據打印onPostExecute方法很好,所以數據來自Web服務就像它應該。爲什麼在JSONParse執行後ArrayList仍爲空?爲什麼在應該使用JSON數據填充arraylist時仍然是空的

對不起,如果我忽視了一些基本的東西,我剛開始學習andorid。

public class StaggeredGridActivity extends Activity implements AbsListView.OnScrollListener, AbsListView.OnItemClickListener, AdapterView.OnItemLongClickListener { 

    private static final String TAG = "StaggeredGridActivity"; 
    public static final String SAVED_DATA_KEY = "SAVED_DATA"; 

    private StaggeredGridView mGridView; 
    private boolean mHasRequestedMore; 
    private SampleAdapter mAdapter; 

    //JSON FIELDS SETUP 

    //URL 
    String url = "http://.../web_services/get_items_test.php"; 

    //JSON Node Names 
    private static final String TAG_ARRAY = "items"; 
    private static final String TAG_ID = "id"; 
    private static final String TAG_ITEMNAME = "iname"; 
    private static final String TAG_NEWPRICE = "new_price"; 
    private static final String TAG_STORENAME = "store_name"; 
    private static final String TAG_CURR = "curr"; 

    //JSON ARRAY 
    JSONArray items = null; 

    //ITEMS LIST 
    ArrayList<Item> item_list = new ArrayList<Item>(); 



    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_sgv); 

     //Execute JSON 
     new JSONParse().execute(); 

     //PRINTS OUT 0! 
     System.out.println(item_list.size()); 
     setTitle("SGV"); 
     mGridView = (StaggeredGridView) findViewById(R.id.grid_view); 

     //LayoutInflater layoutInflater = getLayoutInflater(); 

     //View header = layoutInflater.inflate(R.layout.list_item_header_footer, null); 
     //View footer = layoutInflater.inflate(R.layout.list_item_header_footer, null); 
     //TextView txtHeaderTitle = (TextView) header.findViewById(R.id.txt_title); 
     //TextView txtFooterTitle = (TextView) footer.findViewById(R.id.txt_title); 
     //txtHeaderTitle.setText("THE HEADER!"); 
     //txtFooterTitle.setText("THE FOOTER!"); 

     //mGridView.addHeaderView(header); 
     //mGridView.addFooterView(footer); 
     mAdapter = new SampleAdapter(this, R.id.txt_line1, item_list); 

     // do we have saved data? 
     /*if (savedInstanceState != null) { 
      mData = savedInstanceState.getStringArrayList(SAVED_DATA_KEY); 
     } 
     */ 
     //if (mData == null) { 
     // mData = SampleData.generateSampleData(); 
     //} 
     //  
     //for (String data : mData) { 
     //mAdapter.add(data); 
     //} 

     mGridView.setAdapter(mAdapter); 

     /*mGridView.setOnScrollListener(this); 
     mGridView.setOnItemClickListener(this); 
     mGridView.setOnItemLongClickListener(this);*/ 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.menu_sgv_dynamic, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
      case R.id.col1: 
       mGridView.setColumnCount(1); 
       break; 
      case R.id.col2: 
       mGridView.setColumnCount(2); 
       break; 
      case R.id.col3: 
       mGridView.setColumnCount(3); 
       break; 
     } 
     return true; 
    } 

    /*@Override 
    protected void onSaveInstanceState(final Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putStringArrayList(SAVED_DATA_KEY, item_list); 
    } 
    */ 
    @Override 
    public void onScrollStateChanged(final AbsListView view, final int scrollState) { 
     Log.d(TAG, "onScrollStateChanged:" + scrollState); 
    } 

    @Override 
    public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount, final int totalItemCount) { 
     Log.d(TAG, "onScroll firstVisibleItem:" + firstVisibleItem + 
          " visibleItemCount:" + visibleItemCount + 
          " totalItemCount:" + totalItemCount); 
     // our handling 
     if (!mHasRequestedMore) { 
      int lastInScreen = firstVisibleItem + visibleItemCount; 
      if (lastInScreen >= totalItemCount) { 
       Log.d(TAG, "onScroll lastInScreen - so load more"); 
       mHasRequestedMore = true; 
       // onLoadMoreItems(); 
      } 
     } 
    } 
    /*private void onLoadMoreItems() { 
     final ArrayList<Item> item = JSONParse.execute(); 
     for (String data : sampleData) { 
      mAdapter.add(data); 
     } 
     // stash all the data in our backing store 
     mData.addAll(sampleData); 
     // notify the adapter that we can update now 
     mAdapter.notifyDataSetChanged(); 
     mHasRequestedMore = false; 
    }*/ 

    @Override 
    public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { 
     Toast.makeText(this, "Item Clicked: " + position, Toast.LENGTH_SHORT).show(); 
    } 

    @Override 
    public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) 
    { 
     Toast.makeText(this, "Item Long Clicked: " + position, Toast.LENGTH_SHORT).show(); 
     return true; 
    } 

    /*****************************************JSON********************************************/ 
    //GET JSON DATA FROM URL 
    private class JSONParse extends AsyncTask<String, String, JSONObject> { 

     JSONparser jParser = new JSONparser(); 
     private JSONObject json; 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
     } 

     @Override 
     protected JSONObject doInBackground(String... args) { 

      // Getting JSON from URL 
      json = jParser.getJSONFromUrl(url); 
      return json; 

     } 

     @Override 
     public void onPostExecute(JSONObject json) { 

      try { 
       // Getting JSON Array from URL 
       items = json.getJSONArray(TAG_ARRAY); 

       for(int i = 0; i < items.length(); i++){ 

        JSONObject c = items.getJSONObject(i); 

        // Storing JSON item in a Variable 
        String id = c.getString(TAG_ID); 
        String itemname = c.getString(TAG_ITEMNAME); 
        String newprice = c.getString(TAG_NEWPRICE); 
        String storename = c.getString(TAG_STORENAME); 
        String curr = c.getString(TAG_CURR); 

        Item item = new Item(); 

        item.setItemId(id); 
        item.setItemName(itemname); 
        item.setItemPrice(newprice); 
        item.setStoreName(storename); 
        item.setItemCurrency(curr); 

        item_list.add(item); 

        //This is good! It prints out all item names 
        System.out.println(item_list.get(i).getItemName()); 

       } 

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


     } 
    } 
} 

回答

1

將行on後的onCreate中的所有代碼放到一個函數中。在onPostExecute()中調用該函數。

+0

Thx,它的工作原理。是否在像Hades這樣的背景中提到了這個執行的原因? –

+0

是的。你必須等到列表填入doInBackground。然後在onPostExecute處理列表。在立即調用execute()之後,下一行將被執行,但是在下載準備就緒之前。 – greenapps

+0

@MunezNS標記答案是正確的,如果它幫助你解決問題。 – Hades

1

new JSONParse().execute(); - 在因此,當它在你的oncreate方法執行System.out.println(item_list.size());,數據仍然沒有被下載後臺完成...使用onPostExecute來更新您的視圖中的數據已經被下載後,...這是負載你的適配器......你需要了解爲什麼你要在AsyncTask中做這件事。仍在執行

事情到此效果,

@Override 
      public void onPostExecute(JSONObject json) { 

       try { 
        // Getting JSON Array from URL 
        items = json.getJSONArray(TAG_ARRAY); 

        for(int i = 0; i < items.length(); i++){ 

         JSONObject c = items.getJSONObject(i); 

         // Storing JSON item in a Variable 
         String id = c.getString(TAG_ID); 
         String itemname = c.getString(TAG_ITEMNAME); 
         String newprice = c.getString(TAG_NEWPRICE); 
         String storename = c.getString(TAG_STORENAME); 
         String curr = c.getString(TAG_CURR); 

         Item item = new Item(); 

         item.setItemId(id); 
         item.setItemName(itemname); 
         item.setItemPrice(newprice); 
         item.setStoreName(storename); 
         item.setItemCurrency(curr); 

         item_list.add(item); 

         //This is good! It prints out all item names 
         System.out.println(item_list.get(i).getItemName()); 
        } 

        mAdapter = new SampleAdapter(this, R.id.txt_line1, item_list); 

        for (Item data : item_list) { 
         mAdapter.add(data); 
        } 

        mGridView.setAdapter(mAdapter); 

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

Thx對你的答案冥王星。您通過mAdapter.add(數據)和平的代碼幫助了很多。沒有那部分代碼,GridView沒有被填充。我認爲這足以將item_list傳遞給SampleAdapter構造函數。如果你能向我解釋爲什麼只傳遞item_list還不夠,我將不勝感激。 –

+0

認爲適配器是數據和視圖之間的橋樑。因此,您需要將數據添加到適配器中,以使其在視圖中工作... – Hades

0

查詢,當你打印出來的結果還沒有準備好。 爲您的AsyncTask提供方法。在那裏您確定查詢執行已完成,並且可以調用包含該方法中所有代碼的函數。

相關問題