0

Help - read all the relevant threads but my onPostExecute is not being called.

I'm trying to dynamically create the autocomplete list for an AutoCompleteTextView by running the list builder on a separate thread using AsyncTask

Here's the basic code.... any ideas?

  _artist = (AutoCompleteTextView)findViewById(R.id.artist);  
  _artist.addTextChangedListener(new TextWatcher() 
    {
        public void afterTextChanged(Editable s) 
        {
            _artist.setAdapter(null);
            _fetcher = new AutoCompleteFetcher(_artist);
            _fetcher.execute();        
        }
    }

    public class AutoCompleteFetcher extends AsyncTask<Void, Void, Void> 
    {       
        private AutoCompleteTextView _textView;
        private String[] _matches;

        public AutoCompleteFetcher(AutoCompleteTextView v) 
        {
            super();
            _textView = v;
        }

        protected Void doInBackground(Void... v)
        {   
            _matches = _getMatches();               
            return null;
        }

        private String[] _getMatches()
        {   
            // fill the list....... code removed here
            // returns populated String[]
        }

        @Override
        protected void onPostExecute(Void result) 
        {   
            ArrayAdapter<String> adapter = 
                    new ArrayAdapter<String>(_textView.getContext(),
                        android.R.layout.simple_list_item_1,_matches);
            _textView.setAdapter(adapter);
        }
}
milleph
  • 462
  • 5
  • 20
  • Why do you not return the getMatches() results to onPostExecute() and then assign them there to _matches? – nkr Jul 14 '12 at 15:28
  • true, i could do that, but the problem i have is onPostExecute is never called. I just read elsewhere that AutoCompleteTextView uses AsyncTask internally so this is a bad idea... perhaps that is the problem? – milleph Jul 14 '12 at 15:34

1 Answers1

0

I would have thought that your code was ok, but if you look at this thread, maybe not. Potentially some versions of Android don't handle this case as expected.

Anyway, I think the problem might be that you declare your AsyncTask generic parameters as all Void. I think the idea is supposed to be that the task produces some kind of result, and that result is passed to onPostExecute(). It looks like you are using a member variable _matches to pass the result of the background work from doInBackGround() to onPostExecute(). I think Android's designers intended for you to use the return value of doInBackground() and the parameter to onPostExecute() to accomplish this.

So, try this instead:

public class AutoCompleteFetcher extends AsyncTask<Void, Void, String[]> 
{       
    private AutoCompleteTextView _textView;

    public AutoCompleteFetcher(AutoCompleteTextView v) 
    {
        super();
        _textView = v;
    }

    @Override
    protected String[] doInBackground(Void... v)
    {   
        return _getMatches();               
    }

    private String[] _getMatches()
    {   
        // fill the list....... code removed here
        // returns populated String[]
        // TODO: it seems like this method should really just be moved into 
        //  doInBackground().  That said, I don't think this is your problem.
    }

    @Override
    protected void onPostExecute(String[] result) 
    {   
        ArrayAdapter<String> adapter = 
                new ArrayAdapter<String>(_textView.getContext(),
                    android.R.layout.simple_list_item_1, result);
        _textView.setAdapter(adapter);
    }
}
Community
  • 1
  • 1
Nate
  • 31,017
  • 13
  • 83
  • 207