Извлечение данных (responsebody) с помощью HttpClient в AsyncTask и возврат данных вне AsyncTask в поток пользовательского интерфейса - PullRequest
0 голосов
/ 16 марта 2010

В основном мне интересно, как я могу делать то, что написал в теме. Я просмотрел много учебников по AsyncTask, но не могу заставить его работать. У меня есть небольшая форма (EditText), которая будет принимать то, что пользователь вводит там, и делать это в URL-запрос для приложения, чтобы найти и затем отобразить результаты.

То, что я думаю, сработает, примерно так: в моей основной деятельности у меня есть строка с именем responseBody. Затем пользователь нажимает кнопку поиска, она переходит к моей функции поиска и оттуда вызывает метод GrabUrl с URL-адресом, который запустит asyncdata, и когда этот процесс завершится, метод onPostExecute будет использовать функцию activity.this.setResponseBody (content ).

Вот так выглядит мой код, упрощенный с наиболее важными частями (я думаю).

public class activity extends Activity {
   private String responseBody;
       @Override

   public void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      initControls();
   }

   public void initControls() {

      fieldSearch = (EditText) findViewById(R.id.EditText01);
      buttonSearch = (Button)findViewById(R.id.Button01);
      buttonSearch.setOnClickListener(new Button.OnClickListener() { public void onClick (View v){ search();
    }});

  }

    public void grabURL(String url) {
    new GrabURL().execute(url);
}

    private class GrabURL extends AsyncTask<String, Void, String> {
       private final HttpClient client = new DefaultHttpClient();
       private String content;
       private boolean error = false;
       private ProgressDialog dialog = new ProgressDialog(activity.this);

       protected void onPreExecute() {
        dialog.setMessage("Getting your data... Please wait...");
        dialog.show();
       }

   protected String doInBackground(String... urls) {
      try {
         HttpGet httpget = new HttpGet(urls[0]);
     ResponseHandler<String> responseHandler = new BasicResponseHandler();
     content = client.execute(httpget, responseHandler);
      } catch (ClientProtocolException e) {
     error = true;
     cancel(true);
      } catch (IOException e) {
     error = true;
     cancel(true);
      }

      return content;
   }

   protected void onPostExecute(String content) {
      dialog.dismiss();
      if (error) {
             Toast toast = Toast.makeText(activity.this, getString(R.string.offline), Toast.LENGTH_LONG);
         toast.setGravity(Gravity.TOP, 0, 75);
         toast.show();
      } else {
     activity.this.setResponseBody(content);
      }
    }
     }

        public void search() {

          String query = fieldSearch.getText().toString();

          String url = "http://example.com/example.php?query=" + query; //this is just an example url, I have a "real" url in my application but for privacy reasons I've replaced it 

          grabURL(url); // the method that will start the asynctask

          processData(responseBody); // process the responseBody and display stuff on the ui-thread with the data that I would like to get from the asyntask but doesn't obviously

         }

1 Ответ

0 голосов
/ 17 марта 2010

Проигнорируйте этот ответ, я не читал комментарии перед публикацией, но я оставлю оригинальное содержание здесь, для справки, кто-то может найти полезным, возможно.


setResponseBody (содержимое строки) должно вызывать runOnUiThread ():

public void setResponseBody(String content) {
    runOnUiThread(new Runnable() {
        public void run() {
            //set the content here
        }
    }
}

В Android (и многих других инструментальных средствах с графическим интерфейсом (QT, WinForms, iirc)) вы можете изменять представления только в потоке, который их создал (в потоке пользовательского интерфейса). Вызов runOnUiThread () запускает предоставленный runnable в этом потоке пользовательского интерфейса.

...