studio jakewharton butter bindview android dependency-injection butterknife

android - bindview - com jakewharton butterknife 8.1 0



Inyección de visón (1)

Me encontré con una muy interesante biblioteca de inyección de dependencias llamada ButterKnife . Usando ButterKnife es fácilmente posible inyectar Vistas en actividades o fragmentos.

class ExampleActivity extends Activity { @InjectView(R.id.title) TextView title; @InjectView(R.id.subtitle) TextView subtitle; @InjectView(R.id.footer) TextView footer; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.simple_activity); ButterKnife.inject(this); // TODO Use "injected" views... } }

Sin embargo, si usa Dependency Injection, esas vistas deben ser public para que Butterknife pueda inyectarlas (al usar private resultados de campos private en una excepción, los fields must not be private or static ).

En mi proyecto anterior siempre hice que todos los campos de miembros (incluidos los puntos de vista) fueran private ya que pensé que esta era la mejor práctica (ocultar información, etc.). Ahora me pregunto si existe una razón por la cual no se deben hacer public todos los puntos de vista. En este caso, no puedo usar ButterKnife pero quiero usarlo porque simplifica mucho el código.


En primer lugar, Butter Knife no es una biblioteca de inyección de dependencia. Puede considerarlo como una biblioteca de reducción estándar ya que todo lo que hace es reemplazar findViewById y varias llamadas a setXxxListener .

La razón por la que Butter Knife requiere que las vistas no sean privadas es que en realidad genera código que establece los campos. El código que genera vive en el mismo paquete que su clase y es por eso que el campo debe ser privado del paquete, protegido o público. Si el campo era privado, el código generado no se compilaría porque no puede acceder al campo privado.

El código generado se ve así:

public static void inject(ExampleActivity target, ExampleActivity source) { target.title = (TextView) source.findViewById(R.id.title); target.subtitle = (TextView) source.findViewById(R.id.subtitle); target.footer = (TextView) source.findViewById(R.id.footer); }

Cuando llamas a ButterKnife.inject(this) busca esta clase de generación y llama al método de inject con tu instancia de ExampleActivity como el destino para los campos y la fuente para findViewById llamadas a findViewById .