¿Cómo utilizar AsyncTask para mostrar un ProgressDialog mientras realiza un trabajo de fondo en Android?

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

Estoy desarrollando mi primera aplicación de Android y necesito un ProgressDialog para ser demostrado mientras que una tarea del fondo, en este caso apenas una llamada del HTTP en el servidor, sucede. Hice un poco de estudio sobre esto y también he comprobado otros hilos relacionados con este tema.

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

Android muestra ProgressDialog hasta que la actividad terminó de cargar la interfaz de usuario

Android SplashScreen

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

Entre otros.

Que tengo que escribir un poco de código:

1) En Mi Actividad declaro que una variable es del 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 el doInBackGround es donde llamo un método estático que realmente hace la petición 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<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 que construye el ProgressDialog y llama a 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 todo, creo que esto fue suponer que mostrar un diálogo de progreso mientras el AsyncTask consulta el servidor en segundo plano, pero lo que obtienes es NO barra de progreso hasta que llega la respuesta del servidor y que por 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 revisar este código y simplemente no puedo encontrar dónde lo puse mal. ¿Alguna sugerencia?

Gracias de antemano.

Hola, como sugiere Charlie Sheen (???) en la primera respuesta para este hilo he intentado 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 la 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(".+@.+\\.[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<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); } }; 

Coloque su ProgressDialog en onPreExecute , código de ejemplo 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 , acaba de poner esta línea dentro:

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

La solución final que funcionó es tomar todo el código de OnClickListener al método doInBackground desde la implementación de 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 se realiza en la implementación de EfetuaLogin 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(".+@.+\\.[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); 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 documentación AsyncTask dice que podría utilizar ejecutar para pasar parámetros a su tarea.

Gracias.

  • El indicador de progreso indeterminado ActionBarSherlock no desaparecerá en el simulador
  • Barra de progreso personalizada en Android?
  • ProgressDialog en AsyncTask
  • Diálogo de progreso de Android
  • ¿Hay alguna forma de obtener el progreso de subida correctamente con HttpUrlConncetion?
  • Android Descargar Progress
  • Mostrar una barra de progreso cuando se está cargando una actividad
  • Cambio del mensaje de diálogo de progreso durante la ejecución
  • ¿Cómo puedo mostrar un diálogo Progress entre dos actividades?
  • Uso de ProgressDialog en ActionBar (Android)
  • Quiero un círculo de progreso en lugar de un diálogo de progreso
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.