2012-02-23 13 views
6

Tengo un onClickListener que desencadena una llamada de red, así que me gustaría tener alguna manera de mostrarle al usuario que las comunicaciones están en progreso. El problema al que me estoy enfrentando es que parece que no puedo lanzar un ProgressDialog o cambiar la UI de ninguna manera antes de que se realice la llamada dentro de OnClick Listener. Todo el código funciona bien, pero los cambios de la interfaz de usuario no entran en vigencia hasta que se ejecuta todo el código en onClickListener.¿OnClickListener no actualiza la UI hasta que se haya ejecutado todo el código dentro de Android?

Me preguntaba si mi problema es simplemente que una clase interna anónima como un onclicklistener solo puede actualizar la UI al final de su ejecución. O tal vez mi código es simplemente malo.

Gracias de antemano

A continuación se muestra el código para el oyente onclick:

 relayButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       cPanel.throwProgress(NCDTCPRelayActivity.this); 

       System.out.println(tvSocketConnection.getText().toString()); 

       if (relayStatusArray[relayNumber] == 0) 
       { 
        if (cPanel.TurnOnRelay(relayNumber, 1) == false) 
        { 
         changeTitleToRed(); 
        }else{ 
         changeTitleToGreen(); 
        } 
       } 
       else { 
        if (cPanel.TurnOffRelay(relayNumber, 1) == false){ 
         changeTitleToRed(); 
        }else{ 
         changeTitleToGreen(); 
        } 
       } 
       cPanel.hideProgress(NCDTCPRelayActivity.this); 
      } 
     }); 

Aquí está el código para el throwProgress y hideProgress respectivamente (estos se encuentran en una subclase de la actividad):

public boolean throwProgress(Context mContext) { 
    System.out.println("INSIDE THROWPROGRESS"); 
    try { 
     tempDialog = ProgressDialog.show(mContext, "Connecting", "Connecting", true); 
    } 
    catch (RuntimeException e) { 
     return false; 
    } 
    return true; 
} 
public boolean hideProgress(Context mContext) { 
    System.out.println("OUTSIDE THROWPROGRESS"); 
    tempDialog.hide(); 
    return true; 
} 

** Editar Aquí está el nuevo código para el OnClickListener que puse el ejecutable en:

  public void onClick(View v) { 
       cPanel.throwProgress(NCDTCPRelayActivity.this); 
       System.out.println(tvSocketConnection.getText().toString()); 

       handler.post(new Runnable() { 

        @Override 
        public void run() { 
         // TODO Auto-generated method stub 
         if (relayStatusArray[relayNumber] == 0) 
         { 
          if (cPanel.TurnOnRelay(relayNumber, 1) == false) 
          { 
           changeTitleToRed(); 
          }else{ 
           changeTitleToGreen(); 
          } 
         } 
         else { 
          if (cPanel.TurnOffRelay(relayNumber, 1) == false){ 
           changeTitleToRed(); 
          }else{ 
           changeTitleToGreen(); 
          } 
         } 
         cPanel.hideProgress(NCDTCPRelayActivity.this); 
         relayStatusArray = cPanel.getBankStatus(1); 
         updateButtonText(); 
        } 

       }); 
      } 

Respuesta

3

Cambiar la interfaz de usuario de su controlador de clics debería funcionar bien. Es probable que esté haciendo un trabajo pesado en el subproceso de interfaz de usuario y lo esté bloqueando para que el diálogo no se actualice realmente hasta después de que se haya terminado todo el trabajo. Intenta mover todo el trabajo pesado en un AsyncTask (lee this doc si no estás familiarizado con él), oculta el cuadro de diálogo cuando la tarea se completa y mira si eso lo soluciona.

+0

Bueno, la llamada de red está en una AsyncTask, sin embargo, uso el método AsyncTask(). Execute(). Get() para que el subproceso ui espere la respuesta porque todo el programa se usa para obtener esos comandos de red al objetivo y recuperar una respuesta. Es solo un trabajo para que no tengamos una excepción de red en el hilo principal. ¿No se ejecutaría antes el código antes de la llamada antes del código? – Poodimizer

+0

No llame a get() en el hilo principal. Anule AsyncTask.onPostExecute() y controle la respuesta allí. – gngr44

+1

@Poodimizer ¡No hagas eso! De hecho, estás derrotando el objetivo de 'AsyncTask' para empezar convirtiéndolo en una tarea * sincrónica * innecesariamente elaborada. – Santa

3

Todas las actualizaciones de la interfaz de usuario se retrasan en Android, así como en casi todas las plataformas de GUI que existen. Los cambios en el aspecto de una vista nunca se representan de inmediato; en su lugar, el subsistema GUI marca la vista como "necesita volver a dibujar", y llama al draw() un tiempo después en el ciclo del mensaje.

Si desea que algo suceda después de que se haya actualizado la pantalla, use Handler.post(). El código de post() 'ed se ejecutará algún tiempo en el bucle de mensaje, generalmente más tarde que el código de sorteo en cola.

Aside node: Windows GUI es una feliz excepción a esa regla; Usted puede dibujar en una ventana de Windows fuera de WM_PAINT. Pero en Android no puedes.

+0

Intenté agregar un ejecutable y colocar la llamada de red en él, pero todavía no estoy mostrando el ProgressDialog de throwProgressBar. ¿Lo hice correctamente? Agregué una nueva sección en la publicación original con el ejecutable en ella. – Poodimizer

Cuestiones relacionadas