在我的AsyncTask中,我使用Jsoup从网页中提取所有p标记,然后将它们添加到应然后由ArrayAdapter用于填充屏幕的ArrayList中。帖子,但由于某种原因,当我在方法之后检查它时,ArrayList是空的。
@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中的log语句返回0,而我的列表是空的?
答案 0 :(得分:3)
AsyncTask
比你现在使用的可能性更大。基本上AsyncTask是一个线程(默认情况下不能更改UI元素)但它提供了一个特殊功能:它与方法onPostExecute()
中的UI线程同步。
因此,您可以使用此功能在ArrayAdapter
内设置AsyncTask
。您可以随意使用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中异步编程的一个很好的教程:Android Threads, Handlers and AsyncTask
答案 1 :(得分:1)
很可能是因为AsyncTask还没有完成执行。
AsyncTask就是这样,异步。它同时在后台运行。
看起来您希望代码在fillNewsItems()
之前阻塞,直到AsyncTask为止
已经完成,实际上它几乎立即返回,就在启动AsyncTask之后。因此,当您尝试获取列表的大小时,它仍为零,AsyncTask尚未完成。