2012-09-25 28 views
1

不填充在我的AsyncTask,我用Jsoup拉所有p標籤從一個網頁,我將它們添加到一個ArrayList是應該然後可以由ArrayAdapter用來填補與屏幕帖子,但由於某種原因,當我去檢查方法後,ArrayList是空的。的ArrayList中的AsyncTask

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    newsItems = new ArrayList<String>(); 

    fillNewsItems(); 
    setListAdapter(new ArrayAdapter<String>(this, 
      android.R.layout.simple_list_item_1, 
      newsItems)); 
    Log.d("news", Integer.toString(newsItems.size())); 
} 

private class GetNewsItemsTask extends AsyncTask<String, Void, String> { 

    protected String doInBackground(String... urls) { 
     try { 
      Document doc = Jsoup.connect(URL).get(); 
      for (Element e : doc.getElementsByTag("p")) { 
       newsItems.add(e.text()); 
      } 
     } catch (Exception e) {  
      Toast.makeText(getApplicationContext(), "Couldn't fetch articles, try again later.", 
        Toast.LENGTH_SHORT).show(); 
     }   
     return null; 
    } 
} 

private void fillNewsItems() { 
    GetNewsItemsTask getNews = new GetNewsItemsTask(); 
    getNews.execute(URL); 
} 
} 

有沒有人知道爲什麼onCreate中的日誌語句返回0,我的列表是空的?

回答

3

AsyncTask比你現在使用更多的可能性。基本上AsyncTask是一個線程(默認情況下不能更改UI元素),但它提供了一個特殊功能:它在方法onPostExecute()中同步到UI線程。

所以你可以用這個來設置AsyncTask裏面的ArrayAdapter。隨意使用onPreExecute()來顯示信息對話框。

此代碼應爲招:

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    fillNewsItems(); 

    Log.d("news", Integer.toString(newsItems.size())); 
} 

private class GetNewsItemsTask extends AsyncTask<Void, Void, ArrayList<String>> { 

    protected ArrayList<String> doInBackground(Void... urls) { 
     try { 
      ArrayList<String> items = new ArrayList<String>(); 
      Document doc = Jsoup.connect(URL).get(); 
      for (Element e : doc.getElementsByTag("p")) { 
       items.add(e.text()); 
      } 
     } catch (Exception e) { 
      Toast.makeText(getApplicationContext(), "Couldn't fetch articles, try again later.", 
        Toast.LENGTH_SHORT).show(); 
     } 
     return items; 
    } 

    @Override 
    protected void onPostExecute(ArrayList<String> items) { 
     newsItems = items; // I assume that newsItems is used elsewhere. 
          // If that's not the case -> remove it 
     setListAdapter(new ArrayAdapter<String>(this, 
       android.R.layout.simple_list_item_1, 
       items)); 
    } 
} 

private void fillNewsItems() { 
    GetNewsItemsTask getNews = new GetNewsItemsTask(); 
    getNews.execute(); 
} 

這是關於異步編程一個很好的教程安卓:Android Threads, Handlers and AsyncTask

+1

真棒,謝謝!從getNews.execute()中刪除URL並將newsItems更改爲for循環中的項目後,我有一個受歡迎的列表視圖!!! –

1

很可能是因爲AsyncTask尚未完成執行。 AsyncTask就是這樣,異步。它在同一時間在後臺運行。 看起來您期待您的代碼在fillNewsItems()上被阻止,直到AsyncTask 完成爲止,實際上,它在啓動AsyncTask後立即返回。所以當你試圖獲得列表的大小時,它仍然是零,AsyncTask尚未完成。