2011-03-08 19 views
7

Cuál es la mejor forma de usar un controlador. Cualquier ventaja. Todos los ejemplos que he encontrado parecen dar la versión en línea.Uso del controlador Android

El uso de implementos Handler.Callback en el método de interfaz de clase e implementación.

o

El uso de código en línea versión

private Handler mHandler = new Handler(){ ....}; 

Respuesta

5

El término común o estas definiciones de clases en línea son las clases anónimas.

Usted puede leer más sobre la discusión de estos en Java/Android: anonymous local classes vs named classes

esencialmente las principales diferencias son readbility, la velocidad de codificación, la reutilización y el alcance.

Desde el punto de vista de los recursos de la creación clase anónima puede provocar una sobrecarga en el recolector de basura como se discutió en Avoid Creating Unnecessary Objects. No estoy seguro de los detalles exactos de la creación de clase anónima, sin embargo, es lógico que la implementación de la interfaz en la clase sea más eficiente.

@WilliamTMallard ha proporcionado un ejemplo de lo que NO hacer. En su ejemplo, se debe implementar un manejador largo y sintácticamente complejo en la clase en lugar de manipulador anónimo porque es más difícil de leer y editar cuando se define en línea.

0

Esto realmente no es una respuesta a la pregunta anterior, porque no sé lo que "la mejor manera" es, y es probable que depende de que estas haciendo. Sin embargo, explicaré lo que estoy haciendo y por qué.

Estoy escribiendo una aplicación que sirve como un controlador remoto. Hay varias actividades que interactuarán con el dispositivo controlado, y es necesario que sucedan cosas diferentes en función del resultado del comando y la actividad de la que proviene. Dos cosas que no me gustaron de los manejadores son: A) que terminan siendo una especie de construcción de "fregadero de cocina", implementando funcionalidades de diferentes fuentes, y B) que separaron una acción (el envío del comando en mi caso) del procesamiento del resultado de esa acción. Sin embargo, usar un controlador anónimo (el término correcto, soy un novato) como parámetro me permite mantener la lógica unida. Aquí está el pseudocódigo para mi enfoque:

command = "Wake up!"; 

    mDeviceInterface.write(command, new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 
      switch(msg.what) { 
      case DeviceInterface.MESSAGE_TIMEOUT: // Process the timeout. 
       announce("Device not responding."); 
       break; 
      case DeviceInterface.MESSAGE_READ: // Process the response. 
       byte[] readBuf = (byte[]) msg.obj; 
       if (readBuf[0] == 0x05) { 
        // Success, update device status. 
       } else { 
        announce("Error!"); 
        break; 
       } 
      } 
     } 
    }); 

(. Siempre recuerda, esto es probablemente vale exactamente lo que ha pagado por ella;))

2

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

package : android.os 
public class 
Handler 
extends Object 

un manejador le permite enviar y Mensaje de procesos y objetos asociados a Runnable MessageQueue de un hilo. Cada instancia de Handler está asociada con un único hilo y la cola de mensajes de ese hilo. Cuando crea un nuevo Manejador, está vinculado a la fila/cola de mensajes del subproceso que lo está creando. A partir de ese momento, entregará los mensajes y los ejecutables a esa cola de mensajes y los ejecutará a medida que salgan del mensaje. cola.

Hay dos usos principales para un Handler:

  1. para programar mensajes y runnables para ser ejecutados como han señalado algunos en el futuro; y
  2. para poner en cola una acción que se realizará en un subproceso diferente de propio.

Exmaple 1

uso manipulador en la página de bienvenida aplicación.

if (!isFirstIn) { 
    mHandler.sendEmptyMessageDelayed(GO_HOME, SPLASH_DELAY_MILLIS); 
} else { 
    mHandler.sendEmptyMessageDelayed(GO_GUIDE, SPLASH_DELAY_MILLIS); 
} 


/************************************************************************************** 
*1. Handler 
*/ 
private Handler mHandler = new Handler() { 
    public void handleMessage(Message msg) { 
     if(isAuto){ 
      switch (msg.what) { 
      case GO_HOME: 
       goHome(); 
       break; 
      case GO_GUIDE: 
       goGuide(); 
       break; 
      } 
     } 
     super.handleMessage(msg); 
    } 
}; 
private void goHome() { 
    Intent intent = new Intent(SplashActivity.this, MainAct.class); 
    SplashActivity.this.startActivity(intent); 
    SplashActivity.this.finish(); 
} 

private void goGuide() { 
    Intent intent = new Intent(SplashActivity.this, GuideActivity.class); 
    SplashActivity.this.startActivity(intent); 
    SplashActivity.this.finish(); 
} 

Ejemplo 2

red de solicitud de uso Handler en hilo de niño si la solicitud de trabajo puede toma tiempo.

new Thread(new Runnable(){ 
    @Override 
    public void run() { 
     String versionPath = Parameters.getCheckVersionPath(); 
     String result = RequestHelper.doGet(versionPath, null); 
     Message msg = new Message(); 
     Bundle data = new Bundle(); 
     data.putString("result",result); 
     msg.setData(data); 
     handler1.sendMessage(msg); 
    } 
}).start(); 

handler1 = new Handler(){ 
    @Override 
    public void handleMessage(Message msg) { 
     String result = msg.getData().getString("result"); 
     JSONObject obj; 
     try { 
      obj = new JSONObject(result); 
      Map<String, String> versionInfo = Helper.getSoftwareVersion(obj); 
      if (versionInfo != null) { 
       newVersion = versionInfo.get("version"); 
       updateUrl = versionInfo.get("url"); 
      } 
     } catch (JSONException e) { 
      Log.w("net work error!", e); 
     } 
    } 

}; 

Ejemplo 3

uso Handler y temporizador para actualizar barra de progreso.

logobar = (ImageView) findViewById(R.id.splash_bar);//progress bar. 
logobarClipe = (ClipDrawable) logobar.getBackground(); 

timer = new Timer(); 
timer.schedule(new TimerTask() { 
    public void run() { 
     updateLogoBarHandler.sendEmptyMessage(0); 
}}, 0, rate); 


/************************************************************************************** 
*2. Handler 
*/ 
//update progress bar. 
private Handler updateLogoBarHandler = new Handler() { 
    public void handleMessage(Message msg) { 
     if(logobarClipe.getLevel() < 10000){ 
      //1.update image. 
      logobarClipe.setLevel(logobarClipe.getLevel() + rate*2); 

      //2.update text. 
      float percent = logobarClipe.getLevel() /100; 
      String percentTxtVerbose = String.valueOf(percent); 
      String percentTxt = percentTxtVerbose.substring(0, percentTxtVerbose.indexOf('.')) + "%"; 
      bartxt.setText(percentTxt); 

     }else{ 
      timer.cancel(); 
     } 
     super.handleMessage(msg); 
    } 
}; 
0

Existe un peligro al usar clases anónimas en Android. Como se describe en this blog post -

En Java, las clases internas y anónimas no estáticos mantienen una implícita referencia a su clase externa.

Y aquí viene la oportunidad de una fuga.

Por lo tanto, la respuesta breve sería: implementar los métodos de interfaz o utilizar clases internas estáticas (que no tienen una referencia de clase externa).

Por ejemplo, un manejador de fugas de seguridad podría tener este aspecto:

private static class ChangeTextHandler extends Handler { 
    private final WeakReference activity; 

    public ChangeTextHandler(MainActivity activity) { 
     this.activity = new WeakReference<>(activity); 
    } 

    @Override 
    public void handleMessage(Message msg) { 
     MainActivity activity = this.activity.get(); 
     if (activity == null) { 
      Log.e(TAG, "Activity is null ChangeTextHandler.handleMessage()!"); 
      return; 
     } 

     final String text = (String) msg.getData().get(BUNDLE_KEY); 
     if (!TextUtils.isEmpty(text)) { 
      switch (msg.what) { 
       // do something 
      } 
     } 
    } 
} 

hice un blog post around usage of Handlers, por lo que podría ser digno de la comprobación, así :)

Cuestiones relacionadas