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
.