在android数组适配器中使用notifyDataSetChanged时出错 [英] Error using notifyDataSetChanged in android array adapter

查看:42
本文介绍了在android数组适配器中使用notifyDataSetChanged时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

11-06 19:52:25.958: E/AndroidRuntime(29609):java.lang.IllegalStateException: 适配器的内容有更改但 ListView 没有收到通知.确保适配器的内容不是从后台线程修改的,而是仅来自 UI 线程.[在 ListView(-1, 类android.widget.ListPopupWindow$DropDownListView)与适配器(类com.example.parkfoxxlight_android.PlacesAutoCompleteAdapter)]

11-06 19:52:25.958: E/AndroidRuntime(29609): java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(-1, class android.widget.ListPopupWindow$DropDownListView) with Adapter(class com.example.parkfoxxlight_android.PlacesAutoCompleteAdapter)]

完整日志:http://pastebin.com/Hx7k28Rm

适配器的完整代码:http://pastebin.com/TfH1bXE3 我正在使用 https://developers.google.com/places/training/autocomplete-android 和它有相当多的默认代码,所以谷歌代码中似乎有错误?

Full code of adapter: http://pastebin.com/TfH1bXE3 I am using the example from https://developers.google.com/places/training/autocomplete-android and it has quite the default code so it seems there is a bug in the google code?

应用程序有时会崩溃并显示上述错误消息.

The app crashes only sometimes with the above error message.

protected void publishResults(CharSequence constraint,
        FilterResults results) {

    if (results != null && results.count > 0) {
        notifyDataSetChanged();
    } else {
        notifyDataSetInvalidated();
    }
}

活动http://pastebin.com/FYzYtvXY:

public class CityActivity extends Activity{

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.city);

            AutoCompleteTextView autoCompView = (AutoCompleteTextView) findViewById(R.id.autocomplete_city);

            PlacesAutoCompleteAdapter ad = new PlacesAutoCompleteAdapter(this);
            ProgressBar b = (ProgressBar)findViewById(R.id.progressBar1);
            ad.setLoadingIndicator(b);

            autoCompView.setAdapter(ad);
        }
}

任何想法如何解决这个问题?我使用的是 android 4.3.

Any ideas how to fix this? I am on android 4.3.

推荐答案

FilterperformFiltering() 方法在后台线程上运行,您可以通过该方法'重新更改适配器所基于的 resultList.如果您更改该数据列表,并且在那个时间 ListView 访问适配器,它将看到某些内容在它不知情的情况下发生了变化(并且它不会高兴).您应该避免在 performFiltering 方法中使用 resultList 并简单地创建一个新的临时列表:

The Filter's performFiltering() method runs on a background thread and from that method you're changing the resultList on which your adapter is based. If you change that list of data and in that time the ListView access the adapter it will see that something has changed without its knowledge(and it will not be happy). You should avoid using the resultList in the performFiltering method and simply create a new temporary list:

// in the performFiltering method which runs on a background thread:
@Override
protected FilterResults performFiltering(CharSequence constraint) {
     FilterResults filterResults = new FilterResults();
     ArrayList<String> queryResults;
     if (constraint != null && constraint.length() > 0) {
         queryResults = autocomplete(constraint);
     } else {
         queryResults = new ArrayList<String>(); // empty list/no suggestions showing if there's no valid constraint
     }
     filterResults.values = queryResults;
     filterResults.count = queryResults.size();
     return filterResults; // ## Heading ##
}

private List<String> autocomplete(String input) {
   // don't use the here the resultList List on which the adapter is based!
   // some custom code to get items from http connection
     ArrayList<String> queryResults = new ArrayList<String>(); // new list
     queryResults.add("Some String");
     return queryResults;
}

@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
     // update the data with the new set of suggestions
     resultList = (ArrayList<String>)results.values;
     if (results.count > 0) {
         notifyDataSetChanged();
     } else {
         notifyDataSetInvalidated();
     }
}

这篇关于在android数组适配器中使用notifyDataSetChanged时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆