Fetch AutoCompleteTextView suggestions from service in separate thread

后端 未结 3 2182
醉话见心
醉话见心 2021-02-09 16:57

For my AutoCompleteTextView I need to fetch the data from a webservice. As it can take a little time I do not want UI thread to be not responsive, so I need somehow

3条回答
  •  心在旅途
    2021-02-09 17:40

    With the approach above, i also had those problems when typing very fast. I guess it´s because the filtering of the results is done asynchronously by the filter class, so there can be problems when modifying the ArrayList of the Adapter in the ui thread while filtering is done.

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

    However with 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 {
        private Filter mFilter;
    
        private List mSubData = new ArrayList();
        static int counter=0;
    
        public MyAdapter(Context context, int textViewResourceId) {
          super(context, textViewResourceId);
          setNotifyOnChange(false);
    
          mFilter = new Filter() {
            private int c = ++counter;
            private List mData = new ArrayList();
    
            @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 objects = (ArrayList)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;
      }
    }
    

提交回复
热议问题