在android数组适配器中使用notifyDataSetChanged时出错

时间:2013-11-06 19:12:38

标签: java android android-listview

  

11-06 19:52:25.958:E / AndroidRuntime(29609):   java.lang.IllegalStateException:适配器的内容有   已更改,但ListView未收到通知。确保   您的适配器的内容不会从后台线程修改,但是   仅来自UI线程。 [在ListView中(-1,类   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中的示例,它有相当默认的代码,因此Google代码中似乎存在错误?

应用程序有时会因上述错误消息而崩溃。

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上。

2 个答案:

答案 0 :(得分:33)

Filter的{​​{1}}方法在后台线程上运行,并且从该方法更改适配器所基于的performFiltering()。如果您更改了该数据列表,并且在resultList访问适配器的那段时间内,它会看到某些内容在不知情的情况下发生了变化(并且不会感到满意)。您应该避免在ListView方法中使用resultList,只需创建一个新的临时列表:

performFiltering

答案 1 :(得分:0)

试试这个(只是一个猜测):

@Override
    public Filter getFilter() {
        Filter filter = new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults filterResults = new FilterResults();
                if (constraint != null) {
                    ArrayList list = autocomplete(constraint.toString());
                    if (list != null) {
                        filterResults.values = list;
                        filterResults.count = list.size();
                    }
                }
                return filterResults;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                if (results != null && results.count > 0) {
                    //change the underlying data immediately before notifying UI                        
                    resultList = (ArrayList)results.values; 
                    notifyDataSetChanged();
                }
                else {
                    notifyDataSetInvalidated();
                }
            }};
        return filter;
    }