【问题标题】:The content of the adapter has changed bt ListView didn't receive a notification.Make sure the content适配器的内容已更改 bt ListView 没有收到通知。请确保内容
【发布时间】:2013-11-11 05:12:35
【问题描述】:

点击生成的列表时出现错误。

这是我的堆栈跟踪。

java.lang.IllegalStateException:适配器的内容发生了变化,但ListView没有收到通知。确保适配器的内容不是从后台线程修改的,而只是从 UI 线程修改的。 [在 ListView(2131034118, class android.widget.ListView) with Adapter(class android.widget.SimpleAdapter)]

这是初始化代码;

ArrayList<HashMap<String, String>> rssItemList = new ArrayList<HashMap<String, String>>();
List<RSSItem> rssItems = new ArrayList<RSSItem>();
RSSItem rssItem;
RSSParser rssParser = new RSSParser();

这是我的课,它给出了错误。

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

    @Override
    protected String doInBackground(String... args) {
        String url = args[0];
        rssItems = rssParser.getRSSFeedItems(url);
        // updating UI from Background Thread
        runOnUiThread(new Runnable() {
            public void run() {
                FeedDBHandler rssDb = new FeedDBHandler(
                        getApplicationContext());
                // RSSItem rssItem;
                rssItems.size();
                Log.i("size", "size:" + rssItems.size());
                if (rssItems != null) {
                    for (RSSItem item : rssItems) {
                        // creating new HashMap
                        HashMap<String, String> map = new HashMap<String, String>();

                        // Truncating description
                        String description = item.getDescription();
                        if (description.length() > 100)
                            description = description.substring(3, 97)
                                    + "..";

                        // Store in database
                        rssItem = new RSSItem(item.getTitle(),
                                item.getLink(), item.getCategory(),
                                description, item.getPubdate());

                        // check if not exist -notify and insert
                        if (!rssDb.isExistItem(item.getLink())) {
                            createNotification(item.getTitle());
                            rssDb.addFeed(rssItem);
                        }
                        createNotification(item.getTitle());
                        if (map != null) {
                            map.put(TAG_TITLE, item.getTitle());
                            map.put(TAG_LINK, item.getLink());
                            map.put(TAG_CATEGORY, item.getCategory());
                            map.put(TAG_DESRIPTION, description);
                            map.put(TAG_PUB_DATE, item.getPubdate());
                        }

                        rssItemList.add(map);
                    }
                }

                /**
                 * Updating parsed items into listview
                 * */
                // runOnUiThread(new Runnable() {
                // public void run() {
                // adding HashList to ArrayList
                ListAdapter adapter = new SimpleAdapter(
                        AndroidRSSReaderList.this, rssItemList,
                        R.layout.rss_item_list_row, new String[] {
                                TAG_LINK, TAG_TITLE, TAG_DESRIPTION,
                                TAG_PUB_DATE }, new int[] { R.id.page_url,
                                R.id.title, R.id.link, R.id.pub_date });

                // updating listview
                lv.setAdapter(adapter);
                // registerForContextMenu(lv);
                // setListAdapter(adapter);
            }
        });
        return null;
    }

    @Override
    protected void onPostExecute(String result) {
        // dismiss the dialog after getting all products
        // pDialog.dismiss();
        runOnUiThread(new Runnable() {
            public void run() {
                if (rssItem != null) {

                }
            }
        });
    }

这是我的 AsyncTask 类。

【问题讨论】:

  • 请为我尽力吧?

标签: android listview android-listview illegalstateexception


【解决方案1】:

您应该在postexecute方法中设置列表适配器,并且不应通过方向更改或屏幕关闭来重新创建Activity。

【讨论】:

  • Activity 不应通过方向更改或屏幕关闭来重新创建。???请告诉我你的意思,我可以解决我的问题。
【解决方案2】:

AsyncTask 用于执行不在主 (UI) 线程中的代码。您正在做的是在 UI 线程中执行获取代码并尝试在后台线程中设置适配器。所以首先阅读this,然后你可以尝试像这样移动你的代码:

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

@Override
protected String doInBackground(String... args) {
    String url = args[0];
    rssItems = rssParser.getRSSFeedItems(url);
    FeedDBHandler rssDb = new FeedDBHandler(
            getApplicationContext());
    // RSSItem rssItem;
    rssItems.size();
    Log.i("size", "size:" + rssItems.size());

    if (rssItems != null) {
        for (RSSItem item : rssItems) {
            // creating new HashMap
            HashMap<String, String> map = new HashMap<String, String>();

            // Truncating description
            String description = item.getDescription();
            if (description.length() > 100)
                description = description.substring(3, 97)
                        + "..";

            // Store in database
            rssItem = new RSSItem(item.getTitle(),
                    item.getLink(), item.getCategory(),
                    description, item.getPubdate());

            // check if not exist -notify and insert
            if (!rssDb.isExistItem(item.getLink())) {
                createNotification(item.getTitle());
                rssDb.addFeed(rssItem);
            }
            createNotification(item.getTitle());
            if (map != null) {
                map.put(TAG_TITLE, item.getTitle());
                map.put(TAG_LINK, item.getLink());
                map.put(TAG_CATEGORY, item.getCategory());
                map.put(TAG_DESRIPTION, description);
                map.put(TAG_PUB_DATE, item.getPubdate());
            }

            rssItemList.add(map);                


        }
    });

    return rssItemList;
}

@Override
protected void onPostExecute(ArrayList<HashMap<String, String>> rssItemList) {
    ListAdapter adapter = new SimpleAdapter(
    AndroidRSSReaderList.this, rssItemList,
    R.layout.rss_item_list_row, new String[] {
                TAG_LINK, TAG_TITLE, TAG_DESRIPTION,
                TAG_PUB_DATE }, new int[] { R.id.page_url,
                R.id.title, R.id.link, R.id.pub_date });

    // updating listview
    lv.setAdapter(adapter);
    // when updating the adapter call
    // adapter.notifyDataSetChanged();


    // dismiss the dialog after getting all products
    pDialog.dismiss();

}

【讨论】:

  • lv.onDataSetChanged(); 为什么你使用它会给出错误“ListView 类型的 onDataSetChanged() 方法未定义”
【解决方案3】:

您应该始终在 UI 线程上对您的视图进行任何更新,否则您将面临此类错误的风险。声明:

lv.setAdapter(adapter);

...是对您的 ListView 的更新,但由于 doInBackground 未在主线程上运行而失败。 Badoniya 建议使用 AsyncTask 的 postexecute 方法是正确的,因为该方法确实在 UI 线程上运行。

如果您在将适配器绑定到视图后随后更新了适配器的底层数据集,这也适用。您所做的任何更改,以及对 notifyDataSetChanged() 的后续调用,都必须在 UI 线程上。

【讨论】:

    猜你喜欢
    • 2011-09-22
    • 1970-01-01
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 2014-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多