studio patron example ejemplo developer context activity java android design-patterns singleton

java - patron - Singletons vs. Application Context en Android?



singleton android developer (10)

Al recordar esta publicación que enumera varios problemas de uso de Singletons y de haber visto varios ejemplos de aplicaciones de Android que usan el patrón de Singleton, me pregunto si es una buena idea usar Singletons en lugar de instancias individuales compartidas a través del estado de la aplicación global (subclasificando android.os.Aplicación y obtención de este a través de context.getApplication ()).

¿Qué ventajas / inconvenientes tendrían ambos mecanismos?

Para ser honesto, espero la misma respuesta en este patrón de Singleton post con aplicación web, ¡No es una buena idea! pero aplicado a Android. ¿Estoy en lo correcto? ¿Qué es diferente en DalvikVM de lo contrario?

EDITAR: Me gustaría tener opiniones sobre varios aspectos involucrados:

  • Sincronización
  • Reusabilidad
  • Pruebas

Considere ambos al mismo tiempo:

  • tener objetos singleton como instancias estáticas dentro de las clases.
  • tener una clase común (Contexto) que devuelve las instancias singleton para todos los objetos singelton en su aplicación, lo que tiene la ventaja de que los nombres de método en Contexto serán significativos, por ejemplo: context.getLoggedinUser () en lugar de User.getInstance ().

Además, le sugiero que amplíe su Contexto para incluir no solo el acceso a objetos singleton, sino también algunas funcionalidades que necesitan acceso global, como por ejemplo: context.logOffUser (), context.readSavedData (), etc. Probablemente cambie el nombre del Contexto a La fachada tendría sentido entonces.


De la proverbial boca del caballo ...

Al desarrollar su aplicación, es posible que sea necesario compartir datos, contextos o servicios de manera global a través de su aplicación. Por ejemplo, si su aplicación tiene datos de sesión, como el usuario que ha iniciado sesión actualmente, es probable que desee exponer esta información. En Android, el patrón para resolver este problema es hacer que su instancia de aplicación android.app.App sea propietaria de todos los datos globales, y luego tratar su instancia de Aplicación como un singleton con accesores estáticos a los diversos datos y servicios.

Al escribir una aplicación de Android, se le garantiza que solo tendrá una instancia de la clase de aplicación android.app.Así es seguro (y recomendado por el equipo de Google Android) tratarla como un singleton. Es decir, puede agregar de forma segura un método estático getInstance () a la implementación de su aplicación. Al igual que:

public class AndroidApplication extends Application { private static AndroidApplication sInstance; public static AndroidApplication getInstance(){ return sInstance; } @Override public void onCreate() { super.onCreate(); sInstance = this; } }


Desde: Desarrollador> Referencia - Aplicación

Normalmente no hay necesidad de subclase de aplicación. En la mayoría de las situaciones, los singletons estáticos pueden proporcionar la misma funcionalidad de una manera más modular. Si su singleton necesita un contexto global (por ejemplo, para registrar receptores de difusión), a la función para recuperarlo se le puede dar un Contexto que utiliza internamente Context.getApplicationContext () cuando se construye por primera vez el singleton.


En realidad son lo mismo. Hay una diferencia que puedo ver. Con la clase de aplicación puede inicializar sus variables en Application.onCreate () y destruirlas en Application.onTerminate (). Con Singleton tienes que confiar en que VM inicialice y destruya las estadísticas.


Estoy muy en desacuerdo con la respuesta de Dianne Hackborn. Estamos eliminando poco a poco todos los recursos individuales de nuestro proyecto en favor de los objetos ligeros de ámbito de tareas que se pueden recrear fácilmente cuando realmente los necesite.

Los Singletons son una pesadilla para las pruebas y, si se inician de forma perezosa, introducirán "indeterminismo de estado" con efectos secundarios sutiles (que pueden surgir repentinamente cuando se mueven las llamadas a getInstance() de un alcance a otro). La visibilidad se ha mencionado como otro problema, y ​​como los singletons implican un acceso "global" (= aleatorio) al estado compartido, pueden surgir errores sutiles cuando no se sincronizan correctamente en aplicaciones concurrentes.

Considero que es un anti-patrón, es un mal estilo orientado a objetos que esencialmente equivale a mantener un estado global.

Para volver a su pregunta:

Si bien el contexto de la aplicación se puede considerar un singleton en sí mismo, está administrado por el marco y tiene un ciclo de vida , un alcance y una ruta de acceso bien definidos. Por lo tanto, creo que si necesita administrar el estado global de la aplicación, debería ir aquí, a ninguna otra parte. Para cualquier otra cosa, reconsidere si realmente necesita un objeto singleton, o si también sería posible volver a escribir su clase singleton para instanciar en su lugar objetos pequeños y de corta duración que realizan la tarea en cuestión.


La aplicación no es la misma que la de Singleton. Las razones son:

  1. El método de la aplicación (como onCreate) se llama en el hilo de la interfaz de usuario;
  2. El método de singleton puede ser llamado en cualquier hilo;
  3. En el método "onCreate" de la aplicación, puede instanciar Handler;
  4. Si el singleton se ejecuta en un subproceso no-ui, no podría instanciar Handler;
  5. La aplicación tiene la capacidad de administrar el ciclo de vida de las actividades en la aplicación. Tiene el método "registerActivityLifecycleCallbacks". Pero los singletons no tienen la capacidad.

Mis 2 centavos:

Noté que algunos campos singleton / static fueron restablecidos cuando mi actividad fue destruida. Me di cuenta de esto en algunos dispositivos de gama baja 2.3.

Mi caso fue muy simple: solo tengo un archivo privado "init_done" y un método estático "init" que llamé desde activity.onCreate (). Me doy cuenta de que el método init se estaba ejecutando de nuevo en alguna recreación de la actividad.

Si bien no puedo probar mi afirmación, puede relacionarse con CUANDO se creó / usó el singleton / class primero. Cuando la actividad se destruye / recicla, parece que todas las clases a las que solo se refiere esta actividad también se reciclan.

Moví mi instancia de singleton a una subclase de Aplicación. Los accedo desde la instancia de la aplicación. Y, desde entonces, no volvió a notar el problema.

Espero que esto pueda ayudar a alguien.


Mis llamadas de actividad finalizan () (lo que no hace que termine de inmediato, pero lo hará eventualmente) y llama a Google Street Viewer. Cuando lo depuro en Eclipse, mi conexión con la aplicación se interrumpe cuando se llama a Street Viewer, lo que entiendo como la aplicación (completa) que se está cerrando, supuestamente para liberar memoria (ya que una actividad que se está terminando no debería causar este comportamiento) . Sin embargo, puedo guardar el estado en un paquete a través de onSaveInstanceState () y restaurarlo en el método onCreate () de la siguiente actividad en la pila. Ya sea mediante el uso de un Singleton estático o una Aplicación de subclasificación, enfrento y perdí el estado de la aplicación (a menos que lo guarde en un Paquete). Entonces, desde mi experiencia, son lo mismo con respecto a la preservación del estado. Noté que la conexión se perdió en Android 4.1.2 y 4.2.2 pero no en 4.0.7 o 3.2.4, lo que a mi entender sugiere que el mecanismo de recuperación de memoria ha cambiado en algún momento.


Recomiendo mucho los singletons. Si tiene un singleton que necesita un contexto, tenga:

MySingleton.getInstance(Context c) { // // ... needing to create ... sInstance = new MySingleton(c.getApplicationContext()); }

Prefiero Singletons en lugar de la aplicación porque ayuda a mantener una aplicación mucho más organizada y modular, en lugar de tener un lugar donde se debe mantener todo su estado global en toda la aplicación, cada pieza por separado puede cuidarse sola. También es bueno el hecho de que Singletons se inicie perezosamente (a pedido) en lugar de guiarlo por el camino de hacer toda la inicialización por adelantado en Application.onCreate ().

No hay nada intrínsecamente incorrecto con el uso de singletons. Solo úsalos correctamente, cuando tenga sentido. El marco de Android en realidad tiene muchos de ellos, para mantener cachés por proceso de recursos cargados y otras cosas similares.

Además, para aplicaciones sencillas, el subprocesamiento múltiple no se convierte en un problema con los singletons, ya que, por diseño, todas las devoluciones de llamada estándar a la aplicación se envían en el subproceso principal del proceso, por lo que no tendrá lugar el subprocesamiento múltiple a menos que lo introduzca explícitamente a través de subprocesos o implícitamente mediante la publicación de un proveedor de contenido o servicio IBinder a otros procesos.

Solo se atento a lo que estás haciendo. :)


Tuve el mismo problema: ¿Singleton o hacer una subclase android.os.Application?

Primero probé con el Singleton, pero mi aplicación en algún momento hace una llamada al navegador.

Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));

y el problema es que, si el teléfono no tiene suficiente memoria, la mayoría de sus clases (incluso Singletons) se limpian para obtener algo de memoria, de modo que, al regresar del navegador a mi aplicación, se bloqueaba todo el tiempo.

Solución: coloque los datos necesarios dentro de una subclase de clase de aplicación.