2010-10-08 21 views
18

Duplicar posible:
Updating progress dialog in Activity from AsyncTask¿Cómo se usa AsyncTask para mostrar un ProgressDialog mientras se trabaja en segundo plano en Android?

estoy desarrollando mi primer Android de la aplicación y necesito un ProgressDialog que se mostró mientras que una tarea en segundo plano, en este caso sólo una llamada HTTP en el servidor sucede Estudié un poco sobre esto y también he revisado otros hilos relacionados con este tema.

http://developer.android.com/reference/android/os/AsyncTask.html

Android show ProgressDialog until activity UI finished loading

Android SplashScreen

http://android-developers.blogspot.com/2009/05/painless-threading.html

Entre otros.

lo que me dieron para escribir un poco de código:

1) En Mi Actividad declaro una variable a ser de tipo ProgressDialog

public class LoginActivity extends Activity { 

    public static final String TAG = "LoginActivity"; 

    protected ProgressDialog progressDialog; 
... 

2) También he escrito una clase interna para extender AsyncTask como se requiere, aquí en doInBackGround es donde llamo a un método estático que realmente hace la solicitud HTTP POST al servidor, en el lado del servidor he bloqueado los 20s de respuesta del servidor para validar el diálogo de progreso.

class EfetuaLogin extends AsyncTask<Object, Void, String> { 

     private final static String TAG = "LoginActivity.EfetuaLogin"; 

     @Override 
     protected void onPreExecute() 
     { 
      Log.d(TAG, "Executando onPreExecute de EfetuaLogin"); 
     } 


     @SuppressWarnings("unchecked") 
     @Override 
     protected String doInBackground(Object... parametros) { 
      Log.d(TAG, "Executando doInBackground de EfetuaLogin"); 
      Object[] params = parametros; 
      HttpClient httpClient = (HttpClient) params[0]; 
      List<NameValuePair> listaParametros = (List<NameValuePair>) params[1]; 
      String result = null; 
      try{ 
      result = HttpProxy.httpPost(AnototudoMetadata.URL_AUTENTICACAO, httpClient, listaParametros); 
      }catch (IOException e) { 
       Log.e(TAG, "IOException, Sem conectividade com o servidor do Anototudo! " + e.getMessage()); 
       e.printStackTrace(); 
       return result; 
      } 
      return result; 
     } 

     @Override 
     protected void onPostExecute(String result) 
     { 
      progressDialog.dismiss(); 
     } 

    } 

3) Cuando se pulsa el botón I de construir el ProgressDialog ANC llamar a la AsyncTask he creado:

OnClickListener loginListener = new OnClickListener() { 
     public void onClick(View v) { 


//next line should start progress dialog in main thread ????? 
    progressDialog = ProgressDialog.show(LoginActivity.this, "Login in", "Wait a moment please", true, false); 

    //next couple of lines should do an ascyn call to server 
    EfetuaLogin efetuaLogin = new EfetuaLogin(); 
    efetuaLogin.execute(params); 
    try { 
    //recover the server response and sets time out to be 25seconds 
    sResposta = efetuaLogin.get(25, TimeUnit.SECONDS); 

Bueno, eso es todo, creo que esto se supone que debe mostrar un diálogo de progreso mientras que AsyncTask consultaría el servidor en segundo plano, pero lo que obtengo es NO barra de progreso hasta que llega la respuesta del servidor y que durante una fracción de tiempo (menos de 1 segundo) se muestra el progreso y se llama a la siguiente actividad.

Como mencioné, he vuelto a verificar este código y simplemente no puedo encontrar dónde lo hice mal. ¿Alguna sugerencia?

Gracias de antemano.

Hola, como lo sugirió Charlie Sheen (???) En la primera respuesta para este hilo he tryied cambiar un poco de mi código y ahora es como (Desgraciadamente no está funcionando como se esperaba hasta ahora):

OnClickListener loginListener = new OnClickListener() { 
     public void onClick(View v) { 
       //async call???????? 
     new EfetuaLogin().execute(params); 
... 

Y que hacer todo el trabajo para hacer frente a respuesta en el AsyncTask:

class EfetuaLogin extends AsyncTask<Object, Void, String> { 

     private final static String TAG = "LoginActivity.EfetuaLogin"; 

     @Override 
     protected void onPreExecute() 
     { 
      super.onPreExecute(); 
      Log.d(TAG, "Executando onPreExecute de EfetuaLogin"); 
      //inicia diálogo de progresso, mostranto processamento com servidor. 
      progressDialog = ProgressDialog.show(LoginActivity.this, "Autenticando", "Contactando o servidor, por favor, aguarde alguns instantes.", true, false); 
     } 


     @SuppressWarnings("unchecked") 
     @Override 
     protected String doInBackground(Object... parametros) { 
      Log.d(TAG, "Executando doInBackground de EfetuaLogin"); 
      Object[] params = parametros; 
      HttpClient httpClient = (HttpClient) params[0]; 
      List<NameValuePair> listaParametros = (List<NameValuePair>) params[1]; 
      String result = null; 
      try{ 
      result = HttpProxy.httpPost(AnototudoMetadata.URL_AUTENTICACAO, httpClient, listaParametros); 
      }catch (IOException e) { 
       Log.e(TAG, "IOException, Sem conectividade com o servidor do Anototudo! " + e.getMessage()); 
       e.printStackTrace(); 
       return result; 
      } 
      return result; 
     } 

     @Override 
     protected void onPostExecute(String result) 
     { 
      super.onPostExecute(result); 

      if (result == null || result.equals("")) { 
       progressDialog.dismiss(); 
       Alerta 
         .popupAlertaComBotaoOK(
           "Dados incorretos", 
           "Os dados informados não foram encontrados no Sistema! Informe novamente ou cadastre-se antes pela internet.", 
           LoginActivity.this); 
       return; 
      } 

      Log.d(TAG, "Login passou persistindo info de login local no device"); 
      ContentValues contentValues = new ContentValues(); 
      contentValues.put(AnototudoMetadata.LOGIN_EMAIL, sLogin); 
      contentValues.put(AnototudoMetadata.LOGIN_SENHA, sSenha); 
      contentValues.put(AnototudoMetadata.LOGIN_SENHA_GERADA, result); 
      LoginDB loginDB = new LoginDB(); 
      loginDB.addLogin(LoginActivity.this, contentValues); 
      Log.d(TAG, "Persistiu info de login no device, redirecionando para menu principal do Anototudo"); 
      Log.d(TAG, "O retorno da chamada foi ==>> " + result); 
      // tudo ok chama menu principal 
      Log.d(TAG, "Device foi corretametne autenticado, chamando tela do menu principal do Anototudo."); 

      String actionName = "br.com.anototudo.intent.action.MainMenuView"; 
      Intent intent = new Intent(actionName); 
      LoginActivity.this.startActivity(intent); 
      progressDialog.dismiss(); 
     } 

    } 

OnClickListener completo:

OnClickListener loginListener = new OnClickListener() { 
    public void onClick(View v) { 
     Log.d(TAG, "Usuario logado, chamando menu principal"); 
     TextView tLogin = (TextView) findViewById(R.id.loginText); 
     TextView tSenha = (TextView) findViewById(R.id.senhaText); 
     String sLogin = tLogin.getText().toString(); 
     String sSenha = tSenha.getText().toString(); 

     if (sLogin.equals("") | sSenha.equals("")) { 
      Alerta.popupAlertaComBotaoOK("Campos Obrigatórios", 
        "Os campos Login e Senha são obrigatórios para autenticação do Anototudo.", LoginActivity.this); 
      return; 
     } else { 
      Pattern regEx = Pattern.compile("[email protected]+\\.[a-z]+"); 
      Matcher matcher = regEx.matcher(sLogin); 
      if (!matcher.matches()) { 
       Alerta.popupAlertaComBotaoOK("Formato e-mail inválido", "O formato do campo e-mail está inválido", 
         LoginActivity.this); 
       return; 
      } 
     } 


     List<NameValuePair> listaParametros = new ArrayList<NameValuePair>(); 
     listaParametros.add(new BasicNameValuePair("login", sLogin)); 
     listaParametros.add(new BasicNameValuePair("senha", sSenha)); 

     Log.d(TAG, "valores recuperados dos campos de login e senha: " + sLogin + " | " + sSenha); 

     // Reutiliza cliente HttpClient disponibilizado pela Aplicação. 
     AnototudoApp atapp = (AnototudoApp) LoginActivity.this.getApplication(); 
     HttpClient httpClient = atapp.getHttpClient(); 

     //prepara lista de parametros para fazer chamada asíncrona no servidor para autenticar. 
     Object[] params = new Object[2]; 
     params[0] = httpClient; 
     params[1] = listaParametros; 

     //faz chamada assincrona 
     new EfetuaLogin().execute(params); 
    } 
}; 

Respuesta

27

Coloque el ProgressDialog en onPreExecute, código de ejemplo siguiente:

private ProgressDialog pdia; 

@Override 
protected void onPreExecute(){ 
    super.onPreExecute(); 
     pdia = new ProgressDialog(yourContext); 
     pdia.setMessage("Loading..."); 
     pdia.show();  
} 

@Override 
protected void onPostExecute(String result){ 
    super.onPostExecute(result); 
     pdia.dismiss(); 
} 

y en su onClickListener, sólo hay que poner esta línea en el interior:

new EfetuaLogin().execute(null, null , null); 
+0

He intentado esto ya (colocar pd en onPreExecute) tampoco funcionó como se esperaba. También necesito pasar algunos parámetros para ejecutar la tarea, así que no puedo usar execute (null), como mencionaste. ¿Puedo? Tenga en cuenta que necesito pasar algunos parámetros y también recuperar una respuesta de AsyncTask, por eso tengo una llamada al método AsyncTask.get. –

+0

@Marcos Maia: crea un objeto de su 'AsyncTask' y almacena una referencia dentro de él. Ejecútelo sin crear la referencia. 'AsyncTask' es para operaciones cortas, por lo tanto, verifique el resultado en' onPostExecute' en lugar de tratar de obtener la respuesta con su referencia. De todos modos, no puedes obtener la respuesta del servidor tan rápido cuando haces clic en tu 'Botón'. – Wroclai

+1

@Marcos Maia: Coloque todas sus cosas necesarias en 'doInBackground'. El resultado saliente de 'doInBackground' pasa al parámetro' onPostExecute', allí puede verificar la respuesta de su servidor, todo esto dentro de 'AsyncTask'. En cuanto a los valores que pasas en 'AsyncTask', no puedo decirte nada, ya que faltan algunos fragmentos de código. – Wroclai

8

La solución final que trabajaba se está llevando a todo el código de OnClickListener al método de aplicación doInBackground AsyncTask. Ahora el código es como:

OnClickListener:

OnClickListener loginListener = new OnClickListener() { 
     public void onClick(View v) { 
      Log.d(TAG, "Executando OnclickListener"); 

      //faz chamada assincrona 
      new EfetuaLogin().execute(); 
     } 
    }; 

Todo el trabajo que ocurre en EfetuaLogin aplicación AsyncTask:

class EfetuaLogin extends AsyncTask<Object, Void, String> { 

     private final static String TAG = "LoginActivity.EfetuaLogin"; 

     protected ProgressDialog progressDialog; 

     @Override 
     protected void onPreExecute() 
     { 
      super.onPreExecute(); 
      Log.d(TAG, "Executando onPreExecute de EfetuaLogin"); 
      //inicia diálogo de progresso, mostranto processamento com servidor. 
      progressDialog = ProgressDialog.show(LoginActivity.this, "Autenticando", "Contactando o servidor, por favor, aguarde alguns instantes.", true, false); 
     } 


     @SuppressWarnings("unchecked") 
     @Override 
     protected String doInBackground(Object... parametros) { 
      Log.d(TAG, "Executando doInBackground de EfetuaLogin"); 
      TextView tLogin = (TextView) findViewById(R.id.loginText); 
      TextView tSenha = (TextView) findViewById(R.id.senhaText); 
      String sLogin = tLogin.getText().toString(); 
      String sSenha = tSenha.getText().toString(); 

      if (sLogin.equals("") | sSenha.equals("")) { 
       Alerta.popupAlertaComBotaoOK("Campos Obrigatórios", 
         "Os campos Login e Senha são obrigatórios para autenticação do Anototudo.", LoginActivity.this); 
       progressDialog.dismiss(); 
       return null; 
      } else { 
       Pattern regEx = Pattern.compile("[email protected]+\\.[a-z]+"); 
       Matcher matcher = regEx.matcher(sLogin); 
       if (!matcher.matches()) { 
        Alerta.popupAlertaComBotaoOK("Formato e-mail inválido", "O formato do campo e-mail está inválido", 
          LoginActivity.this); 
        progressDialog.dismiss(); 
        return null; 
       } 
      } 


      List<NameValuePair> listaParametros = new ArrayList<NameValuePair>(); 
      listaParametros.add(new BasicNameValuePair("login", sLogin)); 
      listaParametros.add(new BasicNameValuePair("senha", sSenha)); 

      Log.d(TAG, "valores recuperados dos campos de login e senha: " + sLogin + " | " + sSenha); 

      // Reutiliza cliente HttpClient disponibilizado pela Aplicação. 
      AnototudoApp atapp = (AnototudoApp) LoginActivity.this.getApplication(); 
      HttpClient httpClient = atapp.getHttpClient(); 

      String result = null; 
      try{ 
      result = HttpProxy.httpPost(AnototudoMetadata.URL_AUTENTICACAO, httpClient, listaParametros); 
      }catch (IOException e) { 
       Log.e(TAG, "IOException, Sem conectividade com o servidor do Anototudo! " + e.getMessage()); 
       e.printStackTrace(); 
       return result; 
      } 
      return result; 
     } 

     @Override 
     protected void onPostExecute(String result) 
     { 
      super.onPostExecute(result); 

      if (result == null || result.equals("")) { 
       progressDialog.dismiss(); 
       Alerta 
         .popupAlertaComBotaoOK(
           "Dados incorretos", 
           "Os dados informados não foram encontrados no Sistema! Informe novamente ou cadastre-se antes pela internet.", 
           LoginActivity.this); 
       return; 
      } 

      Log.d(TAG, "Login passou persistindo info de login local no device"); 
      ContentValues contentValues = new ContentValues(); 
      contentValues.put(AnototudoMetadata.LOGIN_EMAIL, sLogin); 
      contentValues.put(AnototudoMetadata.LOGIN_SENHA, sSenha); 
      contentValues.put(AnototudoMetadata.LOGIN_SENHA_GERADA, result); 
      LoginDB loginDB = new LoginDB(); 
      loginDB.addLogin(LoginActivity.this, contentValues); 
      Log.d(TAG, "Persistiu info de login no device, redirecionando para menu principal do Anototudo"); 
      Log.d(TAG, "O retorno da chamada foi ==>> " + result); 
      // tudo ok chama menu principal 
      Log.d(TAG, "Device foi corretametne autenticado, chamando tela do menu principal do Anototudo."); 

      String actionName = "br.com.anototudo.intent.action.MainMenuView"; 
      Intent intent = new Intent(actionName); 
      LoginActivity.this.startActivity(intent); 
      progressDialog.dismiss(); 
     } 

    } 

ahora funciona como se esperaba, pero tengo que decir que estoy un poco confundido como la documentación de AsyncTask dice que podrías usar execute para pasar parámetros a tu tarea.

Gracias.

Cuestiones relacionadas