2010-12-27 12 views
7

En el código fuente de Activity.java, veo fuelle algunos métodos:Evitar Getters Interna/setters

public View findViewById(int id) { 
    return getWindow().findViewById(id); 
} 

y la definición del método GetWindow:

public Window getWindow() { 
    return mWindow; 
} 

Pero a medida que las siguientes reglas:

Evitar Getters interna/setters

En los idiomas nativos como C++, es la práctica más común de usar getters (p. Ej. i = getCount()) en lugar de acceder directamente al campo (i = mCount). Esto es un excelente hábito para C++, porque el compilador generalmente puede alinear el acceso , y si necesita restringir o acceso al campo de depuración puede agregar el código en cualquier momento.

En Android, esta es una mala idea. Las llamadas a métodos virtuales son costosas, mucho más que las búsquedas de campo de instancia . Es razonable seguir las prácticas comunes de programación orientadas a objetos y tener getters y setters en la interfaz pública, pero dentro de una clase siempre debe tener acceso a los campos directamente.

Sin un JIT, el acceso directo al campo es aproximadamente 3 veces más rápido que invocar un getiv trivial. Con el JIT (donde acceso de campo directo es tan barato como accediendo a un local), el acceso directo al campo es aproximadamente 7 veces más rápido que invocando un captador trivial. Esto es verdadero en Froyo, pero mejorará en el futuro cuando el JIT incorpore los métodos getter .

así que quiero saber por qué los desarrolladores de Android no tienen acceso a este objeto mWindow directamente? Si el JIT de las versiones actuales de Android no puede alinear el acceso, getWindow(). FindViewById (id) costará más tiempo que mWindow.findViewById (id), y findViewById es un método bastante utilizado.

Respuesta

1

No puede acceder a la propiedad mWindow directamente - it's private. Y no me importaría la velocidad de findViewById, ya que solo necesita llamarlo una vez para cada vista en su diseño en su método onCreate() y almacenar las vistas en los miembros de su actividad. Usted haga llame a findViewById una vez por vista, ¿verdad? ;-)

Sin embargo, si realmente te importan estas cosas, puedes llamar al getWindow(), almacenarlo en una variable local y llamar al findViewById directamente. No recomendaría esto porque todos los aumentos de rendimiento aquí no valen la pena y, de todos modos, quedarán obsoletos con las versiones futuras del JIT.

Si haces esto estaría muy interesado en la cantidad de microsegundos que guardaste. :-)

+0

Gracias por contestar. Ciertamente llamo findViewById una vez para cada vista como dijiste. Tal vez malinterpreté el principio, y ahora está claro. – teok

2

Primero: no puede acceder a él porque es privado.

¿Por qué es privado?

Como dijiste, acceder a los miembros directamente es más rápido. Por otro lado, está invocando un método que no es muy rápido ya que buscará alguna vista en la jerarquía de vistas. Por lo tanto, usar un método en lugar de un acceso directo implicará una pequeña sobrecarga en términos de porcentaje del tiempo total que llevaría realizar esa tarea.

De todos modos, creo que la razón de esto es la encapsulación.

Usted está invocando algo que no posee (que es el SDK de Android). Por lo tanto, no debe hacer suposiciones de lo que está sucediendo "en el otro lado". Simplemente use este método y espere que devuelva la vista que desea (o null si no existe).

Tal vez la próxima versión de Android use un método diferente para buscar una vista, sin llamar al getWindow(). Si usa este método, ellos (Google/Android) simplemente pueden marcar el método como obsoleto y "reenviar" su invocación a la implementación más reciente. Si llamas directamente al getWindow(), tal vez estarías buscando algo que ya no esté allí.

+0

No necesito llamar a getWindow() todo el tiempo para evaluar a los miembros de la vista. No obstante, somos clientes de api para Android, quiero saber por qué escribieron el código así, por qué no esto, vale la pena que me importe. Y gracias por tu respuesta. – teok

+0

No me entendiste bien. En gigerbread, findView podría usar información almacenada en algún lugar del objeto de la ventana. Honeycomb google podría decidir cambiar el sistema de jerarquía de vistas y almacenar la información correspondiente en otro lugar, con otro formato que use otras estructuras de datos. Si usa directamente la ventana, no funcionará en la nueva versión. Si usa findView, google puede invocar la nueva implementación. Más información: http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming) –

+0

mi último enlace debe ser http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming%29 –

0

Tenemos una razón para sonreír ahora ...

La documentación androide que dice para evitar captadores y definidores internas va a cambiar pronto, se añadió supuestamente progruard a la plataforma de pan de jengibre, que hace un buen trabajo de descriptor de acceso de procesos en línea, por favor consulte "Avoid Internal Getters/Setters" is bad advice y estas dos publicaciones SO.

  1. https://stackoverflow.com/a/6716573/892055

  2. https://stackoverflow.com/a/4930538/892055

Cuestiones relacionadas