android - ArrayList 未在 AsyncTask 中填充

标签 android android-asynctask

在我的 AsyncTask 中,我使用 Jsoup 从网页中提取所有 p 标签,然后将它们添加到一个 ArrayList 中,应该然后由 ArrayAdapter 使用它来填充屏幕帖子,但由于某种原因,当我在方法之后检查它时,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,而我的列表是空的?

最佳答案

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 异步编程的好教程:Android Threads, Handlers and AsyncTask

关于android - ArrayList 未在 AsyncTask 中填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12589993/

相关文章:

android - PreferenceActivity 中的 isValidFragment "Method does not override method of its superclass"

android - 开发 iOS 和 Android 原生应用

java - 如何在android中获取具有不同id的url(异步任务)

java - java中asynctask获取进度百分比

android - 如何在从服务器获取数据时实现 ListView

java - Android Room 数据库删除查询不删除任何行

android - 如何离线安装android studio

java - 异步任务执行后通知的非法监视器状态异常

Android:从网络下载图像并在 gridview 上显示它们

java - 未从 AsyncTask/onPostExecute 调用重载 ArrayAdapter 的 getView