0

I have a search function when the user types something in an input and presses enter, an asynctask will fire off to retrieve the results. I want my textview (visibility=gone) which says "Loading" to be displayed before/while the asynctask is running. However, it only displays the loading text for a second, before showing the results in postExecute. So during the few seconds the asynctask is running, I do not see a loading text. Does anyone know why?

As you can see in my code, I have set the loading text to be visible before the asynctask runs and during preExecute in the asynctask, and neither solves the problem.

edit is my EditText, retrieving is my "loading" TextView

Here is my EditText keylistener:

edit.setOnKeyListener(new OnKeyListener() {

            public boolean onKey(View v, int keyCode, KeyEvent event) {

                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    switch (keyCode) {
                    case KeyEvent.KEYCODE_ENTER:
                        retrieving.setVisibility(View.VISIBLE);

                        SearchTask task = (SearchTask) new SearchTask(edit,retrieving);
                        task.execute(edit.getText().toString());

                        try {
                            task.get();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        } catch (ExecutionException e) {
                            e.printStackTrace();
                        }

                        break;
                    }
                }
                return false;
            }
        });

Here is the asynctask:

public class SearchTask extends AsyncTask {

private EditText edit;
private TextView retrieving;

public SearchTask(EditText edit,TextView retreiving, ) {
    this.edit = edit;
    this.retrieving = retreiving;
}

@Override
protected void onPreExecute() {
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(edit.getWindowToken(), 0);
    retrieving.setVisibility(View.VISIBLE);
}

@Override
protected Playlist doInBackground(String... params) {

   //download and parse xml
}

@Override
protected void onPostExecute(Playlist playlist) {

    retrieving.setVisibility(View.GONE);

}
4

3 回答 3

3

OK I read your code further and I see the problem. Your task.get() command is locking up your UI. Therefore your onPreExecute never has a change to run, before getting blocked by task.get().

You should elminate that block of code entirely and do anything that needs to be done in the onPostExecute() method of your async task.

For example:

@Override
protected void onPostExecute(Playlist playlist) {

    retrieving.setVisibility(View.GONE);
    // do something with playist here. Play store it, etc...
}
于 2012-05-10T00:05:39.930 回答
0

after retrieving.setVisibility(View.VISIBLE);

type retrieving.invalidate();

This tells the ui to redraw the view

If for some reason that doesn't work type:

(new Handler()).post (new Runnable() { public void run() { retrieving.invalidate(); } });

Lastly if the above doesn't work try:

(new Handler()).post (new Runnable() { public void run() { retrieving.setVisibility(View.VISIBLE); } });
于 2012-05-09T23:20:07.377 回答
0

Why arent you updating your UI related stuff by calling publishProgress() after you have completed your background job?

In that way it's assured that you call the UI thread in proper way and rearrange your views properly.

Something like this

@Override
protected Playlist doInBackground(String... params) {

//download and parse xml
publishProgress();

}

protected void onProgressUpdate(Integer... progress) {
    //Do your UI Related Stuff Here
}
于 2012-05-09T23:30:09.227 回答