Android ArrayList未在AsyncTask中填充

Android ArrayList未在AsyncTask中填充,android,android-asynctask,Android,Android Asynctask,在我的AsyncTask中,我使用Jsoup从网页中提取所有的p标记,并将它们添加到ArrayList中,ArrayAdapter应使用该列表在屏幕上填充帖子,但由于某些原因,在方法之后检查ArrayList时,ArrayList为空 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); newsItems = new ArrayList<

在我的AsyncTask中,我使用Jsoup从网页中提取所有的p标记,并将它们添加到ArrayList中,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);
}
}
@覆盖
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
newsItems=newArrayList();
fillNewsItems();
setListAdapter(新阵列适配器)(此,
android.R.layout.simple\u list\u item\u 1,
新闻项目),;
Log.d(“news”,Integer.toString(newstims.size());
}
私有类GetNewsItemsTask扩展异步任务{
受保护的字符串doInBackground(字符串…URL){
试一试{
Document doc=Jsoup.connect(URL.get();
对于(元素e:doc.getElementsByTag(“p”)){
添加(例如text());
}
}捕获(例外e){
Toast.makeText(getApplicationContext(),“无法获取文章,请稍后重试。”,
吐司。长度(短)。show();
}           
返回null;
}
}
私有新闻项(){
GetNewsItemsTask getNews=新建GetNewsItemsTask();
执行(URL);
}
}

有人知道为什么onCreate中的log语句返回0,而我的列表为空吗?

很可能是因为AsyncTask尚未完成执行。 异步任务就是这样,异步。它同时在后台运行。 在异步任务完成之前,您似乎希望代码在
fillNewsItems()
上阻塞
已完成,但实际上它几乎在启动异步任务后立即返回。因此,当您试图获取列表的大小时,它仍然为零,表示AsyncTask尚未完成。

很可能是因为AsyncTask尚未完成执行。 异步任务就是这样,异步。它同时在后台运行。 在异步任务完成之前,您似乎希望代码在
fillNewsItems()
上阻塞 已完成,但实际上它几乎在启动异步任务后立即返回。因此,当您试图获取列表的大小时,它仍然是零,异步任务尚未完成。

比您现在使用的可能性更大。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();
}
@覆盖
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
fillNewsItems();
Log.d(“news”,Integer.toString(newstims.size());
}
私有类GetNewsItemsTask扩展异步任务{
受保护的ArrayList doInBackground(无效…URL){
试一试{
ArrayList items=新建ArrayList();
Document doc=Jsoup.connect(URL.get();
对于(元素e:doc.getElementsByTag(“p”)){
添加(如text());
}
}捕获(例外e){
Toast.makeText(getApplicationContext(),“无法获取文章,请稍后重试。”,
吐司。长度(短)。show();
}
退货项目;
}
@凌驾
PostExecute上受保护的void(ArrayList项){
newsItems=items;//我假设newsItems在其他地方使用。
//如果不是这样->删除它
setListAdapter(新阵列适配器)(此,
android.R.layout.simple\u list\u item\u 1,
(项目);;
}
}
私有新闻项(){
GetNewsItemsTask getNews=新建GetNewsItemsTask();
getNews.execute();
}
这是一个很好的关于Android异步编程的教程:

比您现在使用的有更多的可能性。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();
}
@覆盖
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
fillNewsItems();
Log.d(“news”,Integer.toString(newstims.size());
}
私有类GetNewsItemsTask扩展异步任务{
受保护的ArrayList doInBackground(无效…URL){
试一试{
ArrayList items=新建ArrayList();
Document doc=Jsoup.connect(URL.get();
对于(元素e:doc.getElementsByTag(“p”)){
添加(如text());
}
}捕获(例外e){
Toast.makeText(getApplicationContext(),“无法获取文章,请稍后重试。”,
吐司。长度(短)。show();
}
退货项目;
}
@凌驾
PostExecute上受保护的void(ArrayList项){
newsItems=items;//我假设newsItems在其他地方使用。
//如果不是这样->删除它
setListAdapter(新阵列适配器)(此,
android.R.layout.simple\u list\u item\u 1,
(项目);;
}
}
私有新闻项(){
GetNewsItemsTask getNews=新建GetNewsItemsTask();
getNews.execute();
}

这是一个关于Android异步编程的很好的教程:

太棒了,谢谢!从getNews.execute()中删除URL并将newsItems更改为for循环中的项目后,我有了一个填充的LISTVIEW!!!太棒了,谢谢!从getNews.execute()中删除URL,并将newsItems更改为for中的项目之后