¿Cómo implementar un ProgressDialog mientras que Activity solicita un SoapObject desde un Servicio Web?

Sé que ProgressDialog con Threads preguntas se han hecho muchas veces, pero ninguna de las soluciones parecen funcionar para mi proyecto. Básicamente lo que quiero hacer es esto: 1) cuando un usuario hace clic en un botón de la actividad envía una solicitud de autenticación al servidor 2) mientras esto se está haciendo un ProgressDialog se muestra 3) cuando la respuesta viene quiero descartar el ProgressDialog y el objeto devuelto a ser leído e interpretado por la Actividad

Si I: 1) establece el Thread para actualizar el campo Application con la respuesta, el siguiente método (que está fuera del Thread) lanza un NPE al acceder al campo 2) si incluyo el siguiente método en el Thread, el segundo método lanza un 'java.lang.RuntimeException: No se puede crear el controlador dentro de hilo que no ha llamado Looper.prepare ()'

Lo siento por un texto largo, pero estoy perdiendo totalmente sobre esto … Mi código es algo así:

public class XXX extends Activity implements OnClickListener { // (...) private SoapObject returnObject; private String response; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // (...) authProgressDialog = ProgressDialog.show(XXX.this, "", "Authenticating...", true, false); new Thread(new Runnable() { @Override public void run() { authenticate(); // method that calls the API via SOAP authenticateReal(); // method that handles the response } }).start(); mHandler = new Handler() { public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 10: authProgressDialog.dismiss(); break; } } }; } } public void authenticate() { // API stuff (...) AndroidHttpTransport aht = new AndroidHttpTransport(URL); try { aht.call(SOAP_ACTION, soapEnvelope); returnObject = (SoapObject) soapEnvelope.getResponse(); response = returnObject.getProperty("ResponseStatus").toString(); } catch (Exception e) { e.printStackTrace(); } finally { mHandler.sendEmptyMessage(10); } } // Method that needs to access returnObject and reponse objects and // it is here where the NPE's or other exceptions are thrown public void authenticateReal() { // (...) } 

Es mejor utilizar AsyncTask (que es la forma de Android):

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); new TheTask().execute(); } private class TheTask extends AsyncTask<Void, Void, Void>{ @Override protected void onPreExecute() { authProgressDialog = ProgressDialog.show(XXX.this, "", "Authenticating...", true, false); } @Override protected Void doInBackground(Void... params) { authenticate(); // method that calls the API via SOAP authenticateReal(); // method that handles the response return null; } @Override protected void onPostExecute(Void result) { authProgressDialog.dismiss(); } } 

Por cierto … he encontrado esta presentación muy útil (habla de aplicaciones REST, pero puedes aplicar el mismo concepto para diferentes tipos de aplicaciones): Desarrollar aplicaciones cliente de Android REST

Para su último problema, coloque "Looper.prepare ();" en el método run ().

  @Override public void run() { Looper.prepare(); authenticate(); // method that calls the API via SOAP authenticateReal(); // method that handles the response } 

¿Comprobó si su respuesta en el método authenticate () está funcionando correctamente? (utilizando LogCat para mostrar la respuesta)

De lo contrario, utilice mejor AsyncTask (como se sugiere).

Si realmente desea utilizar un Thread lugar de un AsyncTask puede probarlo de esta manera:

 public class XXX extends Activity implements OnClickListener { ... private static int HANDLER_MESSAGE_AUTH_REQUEST_COMPLETE = 10; ... private void performAuthentication(){ authProgressDialog = ProgressDialog.show(XXX.this, "", "Authenticating...", true, false); Thread backgroundThread = new Thread() { @Override public void run() { authenticate(); } } backgroundThread.start(); } private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { switch(msg.what){ case HANDLER_MESSAGE_AUTH_REQUEST_COMPLETE: authProgressDialog.dismiss(); break; } } } private void authenticate(){ // existing authenticate code goes here ... Message msg = Message.obtain(); msg.what = HANDLER_MESSAGE_AUTH_REQUEST_COMPLETE; handler.sendMessage(msg); // existing authenticateReal code goes here ... } } 

Desde su código no está 100% claro donde se asigna la variable mHandler al new Handler() . Para ser claro, en mi código este debe ser un campo private en la propia class . También necesitará un tratamiento de errores en el método authenticate() para enviar un mensaje para descartar el diálogo si encuentra un error.

Como otros ya escribieron, AsyncTask es la manera de proceder.

PERO: AsyncTask y Threads tienen algunas trampas para los elementos de la interfaz de usuario:

Si cambia la orientación del teléfono y no establece android:configChanges="keyboardHidden|orientation" para su Actividad (significa que tiene que manejar onConfigChange por usted mismo) en el Manifest.xml, un cambio de orientación destruirá y recreará su Activity y ContentView y también desconecte el ProgressDialog de la ventana visible (está conectado al antiguo). Android no va a matar a su hilo o AsyncTask. Tampoco lo matará si la actividad se destruye. Esa tarea de fondo continúa hasta que se terminen.

Intentando descartar () su ProgressDialog creada anticipadamente lanza una excepción después de que ContentView se destruyó, ya que ya no forma parte de su ventana. intentar / atrapar un montón en situaciones haciendo algo independiente (asíncrono) de trabajo. Todo lo que usted puede confiar en sólo podría haber desaparecido o sustituido por algo diferente cuando onPostExecute () se llama de nuevo. Eventualmente piensa en registrar cada ASyncTask que inicias en alguna Array en tu Actividad e intenta cancelarlas en tu Activity.onDestroy ().

  • Diálogo de progreso para AsyncTask - Android
  • show ProgressBar o Dialog de un IntentService para el progreso de la descarga
  • El diálogo de progreso no se muestra en la función onActivityResult
  • Excepción android.view.WindowLeaked
  • Mediaplayer actualización de progreso a seekbar no suave?
  • Reexcursión de exoplayer de Android cuando se realiza la búsqueda
  • Barra de progreso personalizada en Android?
  • Android ProgressDialog con el problema de roscado
  • Adición de un diálogo de progreso en una vista web
  • Android Descargar Progress
  • Mostrar diálogo de progreso dentro de DialogFragment
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.