android - Autocomplete-Adapter: java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification -
i'm out of ideas on here. have autocompletetextview
adapter power suggestions. search words geographic regions.
i have 2 kinds of autocomplete-suggestions: searched regions (search history, locally saved) , automplete api called on the network.
sometimes when type in word fast receive following error:
java.lang.illegalstateexception: content of adapter has changed listview did not receive notification. make sure content of adapter not modified background thread, ui thread.
i understand exception in general (the underlying data of adapter should not changed without calling notifydatasetchanged()
on adapter) don't see i'm doing wrong here.
as far understand getfilter()
method running on ui thread , automplete()
method running asynchronously.
here's adapter , can see the autocompregions
changed in getfilter()
method (ui thread) , notifydatasetchanged()
called after.
also, had same problem when using regions retrieved via api , didn't have addition of locally saved region objects, doesn't have those.
any suggestions?
public class placesautocompleteadapter extends arrayadapter<string> implements filterable { private linkedhashmap<string, region> autocompregions; private linkedhashmap<string, region> localregions; drawable clock; drawable search; public void oneventmainthread(meinesuchenchangedevent e) { localregions = meinesuchen.getsearchedregions(); notifydatasetchanged(); } public placesautocompleteadapter(context context, int textviewresourceid) { super(context, textviewresourceid); localregions = meinesuchen.getsearchedregions(); clock = context.getresources().getdrawable(r.drawable.ic_clock_dark); search = context.getresources().getdrawable(r.drawable.ic_search_dark); autocompregions = new linkedhashmap<string, region>(); eventbus.getdefault().register(this); } public void destroy() { eventbus.getdefault().unregister(this); } @override public int getcount() { return autocompregions.size(); } @override public string getitem(int index) { if (index >= autocompregions.size()) { return ""; } return iterables.get(autocompregions.keyset(), index); } @override public view getview(int position, view convertview, viewgroup parent) { view v = convertview; if (v == null) { layoutinflater vi = (layoutinflater) getcontext().getsystemservice( context.layout_inflater_service); v = vi.inflate(r.layout.item_autocomplete, null); } if (position >= autocompregions.size()) { return v; } textview tv = (textview) v.findviewbyid(r.id.text); imageview iv = (imageview) v.findviewbyid(r.id.iv); region r = iterables.get(autocompregions.values(), position); if (r.islocallysaved()) { iv.setimagedrawable(clock); } else { iv.setimagedrawable(search); } tv.settext(r.getname()); return v; } @override public filter getfilter() { filter filter = new filter() { @override protected filterresults performfiltering(charsequence constraint) { filterresults filterresults = new filterresults(); linkedhashmap<string, region> temp = autocomplete(constraint .tostring()); autocompregions.clear(); autocompregions.putall(temp); filterresults.values = new arraylist<string>( autocompregions.keyset()); filterresults.count = autocompregions.size(); return filterresults; } @override protected void publishresults(charsequence constraint, filterresults results) { if (results != null && results.count > 0) { notifydatasetchanged(); } else { notifydatasetinvalidated(); } } }; return filter; } public linkedhashmap<string, region> autocomplete(string input) { if (input == null || input.equals("")) { return localregions; } linkedhashmap<string, region> places = new linkedhashmap<string, region>(); (region r : localregions.values()) { if (r.getname().tolowercase().startswith(input.tolowercase())) { places.remove(r.getname()); places.put(r.getname(), r); } } httpclient client = new defaulthttpclient(); httpconnectionparams.setconnectiontimeout(client.getparams(), 10000); // timeout // limit httpconnectionparams.setsotimeout(client.getparams(), 10000); httpresponse response; input = input.replace(" ", "%20"); string url = staticvalues.autocomplete_base_url + input; log.d("auto", "url: " + url); httpget = new httpget(url); get.setheader(new basicheader(http.content_type, "application/json")); get.addheader("authorization", staticvalues.api_key); get.addheader("accept", "application/json"); try { response = client.execute(get); bufferedreader reader = new bufferedreader(new inputstreamreader( response.getentity().getcontent(), "utf-8")); stringbuilder builder = new stringbuilder(); (string line = null; (line = reader.readline()) != null;) { builder.append(line).append("\n"); } jsonarray ja = new jsonarray(builder.tostring()); gson gson = new gson(); (int = 0; < ja.length(); i++) { jsonobject jo = ja.getjsonobject(i); region r = gson.fromjson(jo.tostring(), region.class); if (!places.containskey(r.getname())) { places.put(r.getname(), r); } } } catch (clientprotocolexception e) { log.e("auc", "exc" + e.tostring()); // todo auto-generated catch block e.printstacktrace(); } catch (ioexception e) { log.e("auc", "exc" + e.tostring()); // todo auto-generated catch block e.printstacktrace(); } catch (exception e) { log.e("auc", "exc" + e.tostring()); // todo auto-generated catch block e.printstacktrace(); } return places; } public region getplace(int index) { if (autocompregions == null || autocompregions.size() == 0) { return iterables.get(localregions.values(), index); } return iterables.get(autocompregions.values(), index); } }
by way: adapter implementation built upon google's example , pure google example has problem too.
Comments
Post a Comment