¿Cómo usar AsyncTask para mostrar un ProgressDialog mientras se trabaja en segundo plano en Android?

Posible duplicado:
Actualización del diálogo de progreso en Activity from AsyncTask

Estoy desarrollando mi primera aplicación para Android y necesito que se muestre ProgressDialog mientras se realiza una tarea en segundo plano, en este caso solo ocurre una llamada http en el servidor. 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 muestra ProgressDialog hasta que la UI de actividad haya terminado de cargarse

Android SplashScreen

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

Entre otros.

Debo escribir un poco de código:

1) En Mi actividad, declaro que una variable es 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 según sea necesario, 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 la respuesta del servidor 20s para validar el diálogo de progreso.

 class EfetuaLogin extends AsyncTask { 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 listaParametros = (List) 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 presiona el botón I, luego compilo el ProgressDialog y llamo al AsyncTask que 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, esto es, creo que se suponía que debía mostrar un diálogo de progreso mientras 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 por una fracción de tiempo (menos de 1 segundo) ) se muestra el progreso y se llama a la siguiente actividad.

Como mencioné, volví 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, intenté cambiar un poco mi código y ahora es como (desafortunadamente 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 lidiar con la respuesta en AsyncTask:

 class EfetuaLogin extends AsyncTask { 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 listaParametros = (List) 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(); } } 

Complete OnClickListener:

 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(".+@.+\\.[az]+"); 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 listaParametros = new ArrayList(); 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); } }; 

Coloque su ProgressDialog en onPreExecute , ejemplo de código a continuación:

 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 , simplemente ponga esta línea dentro:

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

La solución final que funcionó es tomar todo el código del método OnClickListener para doInBackground de la implementación de AsyncTask . Ahora el código es como:

OnClickListener :

 OnClickListener loginListener = new OnClickListener() { public void onClick(View v) { /* Translation note: Original text: "Executando OnClickListener" */ Log.d(TAG, "OnClickListener has been called"); /* Translation note: Original text: "faz chamada assincrona" */ // Make an asynchronous call new EfetuaLogin().execute(); } }; 

Todo el trabajo sucede en la implementación de EfetuaLogin AsyncTask :

 class EfetuaLogin extends AsyncTask { 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 /* Translation note: Original text: "Object... parametros" protected String doInBackground(Object... parameters) { /* Translation note: Original text: "Executando doInBackground de EfetuaLogin" */ Log.d(TAG, "Executing doInBackground of 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("")) { /* Translation notes: 1) "Campos Obrigatórios" -> "Required fields" 2) "Os campos Login e Senha são obrigatórios para autenticação do Anototudo." -> "Login and Password fields are required for Anototudo authentication." Alerta.popupAlertaComBotaoOK("Required fields", "Login and Password fields are required for Anototudo authentication.", LoginActivity.this); progressDialog.dismiss(); return null; } else { Pattern regEx = Pattern.compile(".+@.+\\.[az]+"); Matcher matcher = regEx.matcher(sLogin); if (!matcher.matches()) { /* Translation notes: 1) "Formato e-mail inválido" -> "Invalid email format" 2) "O formato do campo e-mail está inválido" -> "The email field has an invalid format" */ Alerta.popupAlertaComBotaoOK("Invalid email format", "The email field has an invalid format", LoginActivity.this); progressDialog.dismiss(); return null; } } List listaParametros = new ArrayList(); listaParametros.add(new BasicNameValuePair("login", sLogin)); listaParametros.add(new BasicNameValuePair("senha", sSenha)); /* Translation note: Original text: "valores recuperados dos campos de login e senha: " */ Log.d(TAG, "values retrieved from login and password fields:" + sLogin + " | " + sSenha); /* Translation note: Original text: "Reutiliza cliente HttpClient disponibilizado pela Aplicação." */ // Reuses `HttpClient` made available by the Application. 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(); /* Translation notes: 1) "Dados incorretos" -> "Incorrect data" 2) "Os dados informados não foram encontrados no Sistema! Informe novamente ou cadastre-se antes pela internet." -> "The reported data was not found in the System! Please report again or sign up on the internet first." */ Alerta.popupAlertaComBotaoOK( "Incorrect data", "The reported data was not found in the System! Please report again or sign up on the internet first.", LoginActivity.this); return; } /* Translation note: Original text: "Login passou persistindo info de login local no device" */ Log.d(TAG, "Login passed persisting local login info on 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); /* Translation note: Original text: "Persistiu info de login no device, redirecionando para menu principal do Anototudo" */ Log.d(TAG, "Persisting login info on device, redirecting to Anototudo main menu"); /* Translation note: Original text: "O retorno da chamada foi ==>> " */ Log.d(TAG, "The callback was ==>>" + result); /* Translation note: Original text: "tudo ok chama menu principal" */ // everything ok call main menu /* Translation note: Original text: "Device foi corretametne autenticado, chamando tela do menu principal do Anototudo." */ Log.d(TAG, "Device has been correctly authenticated by calling the main menu screen of Annotate."); 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 ya que la documentación de AsyncTask dice que podrías usar execute para pasar parámetros a tu tarea.