Select AutoCompleteTextView sentences from a service in a separate thread

For my AutoCompleteTextView I need to get data from a web service. Since this may take a little time, I don’t want the UI thread to not respond, so I need to somehow extract the data into a separate stream. For example, when retrieving data from SQLite DB, it is very easy to do this using the CursorAdapter method - runQueryOnBackgroundThread . I looked at other adapters, such as ArrayAdapter , BaseAdapter , but could not find anything like it ...

Is there an easy way to achieve this? I can’t just use the ArrayAdapter directly, since the list of sentences is dynamic - I always select the list of sentences depending on user input, so it cannot be pre-programmed and cached for future use ...

If someone can give some advice or examples on this topic - it would be great!

+5
android multithreading autocompletetextview
source share
3 answers

With the above approach, I also had problems typing very quickly. I think this is due to the fact that the filtering of results is performed asynchronously using the filter class, so there may be problems when modifying the ArrayList adapter in the ui stream during filtering.

http://developer.android.com/reference/android/widget/Filter.html

However, with the following approach, everything worked fine.

 public class MyActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); MyAdapter myAdapter = new MyAdapter(this, android.R.layout.simple_dropdown_item_1line); AutoCompleteTextView acTextView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView1); acTextView.setAdapter(myAdapter); } } public class MyAdapter extends ArrayAdapter<MyObject> { private Filter mFilter; private List<MyObject> mSubData = new ArrayList<MyObject>(); static int counter=0; public MyAdapter(Context context, int textViewResourceId) { super(context, textViewResourceId); setNotifyOnChange(false); mFilter = new Filter() { private int c = ++counter; private List<MyObject> mData = new ArrayList<MyObject>(); @Override protected FilterResults performFiltering(CharSequence constraint) { // This method is called in a worker thread mData.clear(); FilterResults filterResults = new FilterResults(); if(constraint != null) { try { // Here is the method (synchronous) that fetches the data // from the server URL url = new URL("..."); URLConnection conn = url.openConnection(); BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line = ""; while ((line = rd.readLine()) != null) { mData.add(new MyObject(line)); } } catch(Exception e) { } filterResults.values = mData; filterResults.count = mData.size(); } return filterResults; } @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence contraint, FilterResults results) { if(c == counter) { mSubData.clear(); if(results != null && results.count > 0) { ArrayList<MyObject> objects = (ArrayList<MyObject>)results.values; for (MyObject v : objects) mSubData.add(v); notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } } } }; } @Override public int getCount() { return mSubData.size(); } @Override public MyObject getItem(int index) { return mSubData.get(index); } @Override public Filter getFilter() { return mFilter; } } 
+10
source share

EDITED: Added a naive way to avoid the drop-down list when you click the sentence.

I am doing something similar in my application:

 private AutoCompleteTextView mSearchbar; private ArrayAdapter<String> mAutoCompleteAdapter; @Override protected void onCreate(Bundle savedInstanceState) { mAutoCompleteAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line); mSearchbar = (AutoCompleteTextView) findViewById(R.id.searchbar); mSearchbar.setThreshold(3); mSearchbar.setAdapter(mAutoCompleteAdapter); mSearchbar.addTextChangedListener(new TextWatcher() { private boolean shouldAutoComplete = true; @Override public void onTextChanged(CharSequence s, int start, int before, int count) { shouldAutoComplete = true; for (int position = 0; position < mAutoCompleteAdapter.getCount(); position++) { if (mAutoCompleteAdapter.getItem(position).equalsIgnoreCase(s.toString())) { shouldAutoComplete = false; break; } } } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { if (shouldAutoComplete) { new DoAutoCompleteSearch().execute(s.toString()); } } } } private class DoAutoCompleteSearch extends AsyncTask<String, Void, ArrayList<String>> { @Override protected ArrayList<String> doInBackground(String... params) { ArrayList<String> autoComplete = new ArrayList<String>(); //do autocomplete search and stuff. return autoComplete; } @Override protected void onPostExecute(ArrayList<String> result) { mAutoCompleteAdapter.clear(); for (String s : result) mAutoCompleteAdapter.add(s); } } 
+9
source share

there was the same solution, except that the problem is that everything is just fine (variables are updated during debugging), but autocomplete fills in a weird way, as in

when I type sco, it has results, but it doesn’t appear in the list, but when I backspace, it shows the result for sco. When debugging, all variables are updated, which only tell me that the user interface is not updated for AutoCompleteTextView. as with a reverse move, it starts to update, and then displays a list of previous computers, then it (at the same time, it updates it with new list items for a new search line. has anyone encountered this problem?

+1
source share

All Articles