La forma adecuada para evitar el método estático (en la clase Util quizás) que se utiliza para actualizar la interfaz de usuario

Soy principiante en Android, he leído y ver si el uso del método estático en la clase Util para actualizar la interfaz de usuario no es bueno para la prueba de unidad. ¿Cómo evitarlo de manera adecuada para mantener el código y la prueba de unidad?

Ejemplo:

class ActivityA { private View view; private MyListener myListener; public void methodB() { Util.callLogicB(this, view, myListener); } } class ActivityB { private View view; private MyListener myListener; public void methodC() { Util.callLogicB(this, view, myListener); } } class Util { public static void callLogicB(Context context, View view, MyListener listener) { // do something with view } } 

Creo que la mejor manera de implementar esto es desconectar completamente sus vistas (su actividad) de su clase lógica. Esto se puede hacer usando una interfaz .

Mira el código a continuación para entender cómo funciona una interfaz. He creado una mainActivity con un textView como un diseño. La clase LogicWithTextUpdate que creé es capaz de actualizar un textView dentro de su mainActivity sin una referencia directa a él .

 public class MainActivity extends Activity implements MyViewListener { //Your logic class, that is capable of updating a textview LogicWithTextUpdate logicWithTextUpdate; @Override protected void onCreate(Bundle savedInstanceState) { //This is just to create a layout (with a textview inside) super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //This creates the class using constructor (and set listener) logicWithTextUpdate = new LogicWithTextUpdate(this); //Update or execute your logic. This will update textview using interface MyViewListener (onUpdateTextListener) //This can be executed using a button (Onclick...) logicWithTextUpdate.doSomeLogic(2); } @Override public void onUpdateTextListener(String text) { //Only here code runs inside your activity class TextView textView = (TextView) findViewById(R.id.textView); textView.setText(text); } } 

Como puedes ver. MainActivity actualizará textview usando un "listener" onUpdateTextListener. Esto se describe dentro de una clase de interfaz:

 public interface MyViewListener { //to be implemented inside your mainActivity public void onUpdateTextListener(String text); } 

Ahora puedo implementar una clase que puede hacer algo de lógica y activar el oyente :

 public class LogicWithTextUpdate { MyViewListener myViewListener; //Constructor here is used to set myViewListener (but you can use a setter like setMyViewListener) public LogicWithTextUpdate(MyViewListener myViewListener) { this.myViewListener = myViewListener; } public void doSomeLogic(int a) { //Some logic a = a * 2; a = a + 1; //Update text using listener. This will update mainActivity, because it is implementing MyViewListener myViewListener.onUpdateTextListener(String.valueOf(a)); } } 

El método doSomeLogic se ejecuta desde su actividad, pero la lógica está dentro de la clase. Una vez ejecutada la lógica, activa myViewListener.onUpdateTextListener que ejecuta onUpdateTextListener dentro de su actividad.

Todo está desconectado . Puede cambiar sus vistas sin ninguna modificación en LogicWithTextUpdate, o cambiar la lógica sin modificaciones en Actitivy . Siempre una buena práctica.

AFAIK, es una buena práctica utilizar exclusivamente clases de utilidad para los métodos estáticos y auxiliares que generalmente devuelven datos primitivos y de referencia, en lugar de actualizar la interfaz de usuario, que debe realizarse sólo en Actividades. Por ejemplo, una clase de utilidad de ejemplo implicaría una serie de métodos tales como:

  • Un método que genera un objeto URL de una URL de solicitud HTTP en formato String
  • Un método que devuelve datos JSON legibles después de conectarse correctamente al servidor HTTP
  • Un método que extrae los datos JSON y los almacena en un ArrayList retornable
  • Un método público, estático que invocó todo lo anterior para finalmente devolver el ArrayList de datos a una Actividad a través de su subproceso de fondo para luego procesar la interfaz de usuario a través de su subproceso de interfaz de usuario

La clase estática es mala para las pruebas unitarias, porque no se puede burlar ni esbozar. Pero la clase de utilidad estática podría ser un enfoque muy útil. Le sugeriría que incluya alguna referencia de interfaz en una clase de utilidad estática, todavía tendrá la misma firma de clase de utilidad, pero le permite cambiar el comportamiento de clases de utilidad para pruebas u otro propósito:

 final class Util { static IUtil util = new DefaultUtil(); private Util() {} public static void callLogicB(Context context, View view, MyListener listener) { util.callLogicB(context, view, listener); } } interface IUtil { public void callLogicB(Context context, View view, MyListener listener); } final class DefaultUtil implemets IUtil { @Override public void callLogicB(Context context, View view, MyListener listener) { // do something with view } } final class TestUtil implemets IUtil { @Override public void callLogicB(Context context, View view, MyListener listener) { //your test logic } } @Before void setUp() { Util.util = new TestUtil(); } 
  • Mejores prácticas / patrones de diseño de codificación para Android
  • MVP para Android: uso seguro Contexto en Presenter
  • Editar entrada de texto con patrón android
  • ¿Debería el renderingThread de un SurfaceView tener el mismo ciclo de vida que la vista o la actividad?
  • ¿Cuál es el principio del patrón de diseño en el desarrollo de Android?
  • ¿Cuál es la diferencia entre "nuevo A ()" y "A.newInstance ()"?
  • Ejemplo de la necesidad del cliente del DESECHO de Androide que implementa el patrón de la ejecución de REST de Virgil Dobjanschi
  • ¿Cómo compartir datos entre dos presentadores en la arquitectura MVP en Android?
  • Buenos patrones de diseño para codificar muchas solicitudes HTTP en Android
  • Android: cómo crear un fondo de patrón?
  • ¿Es Android BaseAdapter un ejemplo de patrón de adaptador?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.