Как использовать ProgressDialog и Async Task для получения метода одновременно - PullRequest
2 голосов
/ 09 ноября 2011

У меня есть общий класс асинхронных задач, который получает ответ от сервера. И я получаю эти ответы, используя метод get. Теперь я знаю, что поток пользовательского интерфейса блокируется, когда я использую метод get, из-за которого мой диалог прогресса не отображается вовремя.

Теперь кто-нибудь может сказать мне альтернативу сделать это? (В каждом случае мне нужно отправлять ответ на действие, которое выполнило вызов execute, чтобы открытие нового действия мне не помогло)

Код: AsyncTask Class

 public class GetDataFromNetwork extends AsyncTask<Void,String,Object> {

protected void onPreExecute() {
    super.onPreExecute();
    progressDialog.show();
} 


 protected Object doInBackground(Void... params) {
    Object result = null;
    try {
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER10);
        new MarshalBase64().register(envelope);
        envelope.dotNet = true;
        envelope.setOutputSoapObject(request);
        AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(ipAddress + webService);
        System.setProperty("http.keepAlive", "true");
        try {
            androidHttpTransport.call(nameSpace + methodName, envelope);
        } catch (Exception e) {

            e.printStackTrace();
            publishProgress(e.getMessage());
        }
        androidHttpTransport.debug = true;
        System.out.println("response: " + androidHttpTransport.requestDump);
        result = envelope.getResponse();
        if(result!=null){
            System.out.println("GetDataFromNetwork.doInBackground() result expection---------"+result);
        }
    } catch (Exception e) {
        System.out.println("GetDataFromNetwork.doInBackground()-------- Errors");
        e.printStackTrace();

    }

    return result;
}

protected void onPostExecute(Object result) {
    super.onPostExecute(result);
    progressDialog.dismiss();
}

Код: Деятельность

GetDataFromNetwork request = new GetDataFromNetwork(
                                        this,
                                        ProgressDialog.STYLE_SPINNER,
                                        getResources().getText(R.string.autenticate).toString());
response= (SoapObject)request.execute().get();

Ответы [ 4 ]

10 голосов
/ 09 ноября 2011

Я все время делаю подобные вещи в своих приложениях, и самым простым способом, который я нашел, было создание интерфейса «обратного вызова» и передача его в качестве параметра моим «AsyncTask».Вы выполняете обработку doInBackground (), а когда она заканчивается, вы вызываете экземпляр Callback из onPostExecute, передавая объект «result» в качестве параметра.

Ниже приведена очень упрощенная версия.

Пример интерфейса обратного вызова:

package example.app;

public interface Callback {

        void run(Object result);
}

Пример использования AsyncTask с использованием интерфейса обратного вызова выше:

public class GetDataFromNetwork extends AsyncTask<Void,String,Object> {
  Callback callback;
  public GetDataFromNetwork(Callback callback){
     this.callback = callback;
  }

   protected void onPreExecute() {
      super.onPreExecute();
      progressDialog.show();
  } 


   protected Object doInBackground(Void... params) {
      Object result = null;
      // do your stuff here
      return result;
  }

  protected void onPostExecute(Object result) {
     callback.run(result);
     progressDialog.dismiss();
  }

}

Пример использования вышеуказанных классов в вашем приложении:

class Example {
   public onCreate(Bundle savedInstanceState){
      //initialize

      GetDataFromNetwork request = new GetDataFromNetwork(new Callback(){
                     public void run(Object result){
                             //do something here with the result
       }});
       request.execute();      
   }
}
1 голос
/ 09 ноября 2011

Как говорит yorkw, проблема в том, что вы заставляете поток пользовательского интерфейса ждать ответ с этим кодом:

response= (SoapObject)request.execute().get();

Как указано в документации для AsyncTask.get () говорит:

Ожидает, если необходимо, чтобы вычисление завершилось, а затем извлекает его результат.

Поскольку поток пользовательского интерфейса ожидает ответа, он не может отображать диалог прогресса. Решение состоит в том, чтобы переместить код, обрабатывающий ответ, в метод onPostExecute ():

protected void onPostExecute(Object result) {
    super.onPostExecute(result);

    // Now we have the response, dismiss the dialog and handle the response
    progressDialog.dismiss();
    response = (SoapObject) result;
}

Этот метод будет вызван после того, как у вас будет ответ. Тем временем поток пользовательского интерфейса может позаботиться о том, чтобы показать диалоговое окно прогресса.

0 голосов
/ 09 ноября 2011

Если вы используете AsyncTask, ваш поток пользовательского интерфейса не будет заблокирован. Вы загружаете свои данные внутри doInBackground()? Потому что это то, где вы должны это делать.

0 голосов
/ 09 ноября 2011

Почему бы не создать другой класс, в который вы поместите ответ, и там у вас будет метод get и set. Затем в onPostExecute вы пишете его с помощью метода set и вызываете обработчик, где вы будете делать все, что захотите ... Это просто идея ...:)

...