studio patron example activity android application-singleton

patron - Singleton de Android con contexto global



patron singleton android (2)

Por la Documentación de Android dice:

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 Context.getApplicationContext() un Contexto que utiliza internamente Context.getApplicationContext() cuando construya por primera vez el singleton.

¿Cómo hago para crear un singleton estático que tenga un contexto global para que sobreviva al cambio de actividad en ejecución en mi aplicación? ¿Es suficiente tener un contexto estático que haga referencia a getApplicationContext ()?


Tengo tal clase en mi aplicación:

public class ApplicationContext { private Context appContext; private ApplicationContext(){} public void init(Context context){ if(appContext == null){ appContext = context; } } private Context getContext(){ return appContext; } public static Context get(){ return getInstance().getContext(); } private static ApplicationContext instance; public static ApplicationContext getInstance(){ return instance == null ? (instance = new ApplicationContext()): instance; } }

y luego, por ejemplo, en Iniciar Actividad inicialízalo:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //init ApplicationContext.getInstance().init(getApplicationContext()); //use via ApplicationContext.get() assert(getApplicationContext() == ApplicationContext.get()); }


Otra edición a la pregunta:

últimamente (a partir de la mayor parte de 2016 y más adelante) lo que he estado haciendo, y sería mi sugerencia para que cualquier desarrollador lo haga como:

Usa Dagger2, solo usa Dagger 2. Donde sea que necesites un Context , hazlo:

@Inject Context context;

y eso es. Mientras esté en ello, inyecte todas las otras cosas que serían un singleton.

Respuesta editada / mejorada:

como esta respuesta se está volviendo un poco popular, mejoraré mi propia respuesta con un código de ejemplo de lo que he estado usando últimamente (a partir de julio de 2014).

Comience por tener la aplicación manteniendo una referencia a sí misma.

public class App extends Application { private static App instance; public static App get() { return instance; } @Override public void onCreate() { super.onCreate(); instance = this; } }

luego, en cualquier singleton que necesite acceso al context , la carga diferentemente de manera segura para subprocesos usando la sincronización de doble verificación como se explica aquí https://.com/a/11165926/906362

private static SingletonDemo instance; public static SingletonDemo get() { if(instance == null) instance = getSync(); return instance; } private static synchronized SingletonDemo getSync() { if(instance == null) instance = new SingletonDemo(); return instance; } private SingletonDemo(){ // here you can directly access the Application context calling App.get(); }

respuesta original:

lo que la documentación sugiere es utilizar un patrón de singleton normal

public class SingletonDemo { private static SingletonDemo instance = null; private SingletonDemo() { } public static SingletonDemo getInstance() { if (instance == null) { instance = new SingletonDemo (); } return instance; } }

e incluir en su interior un método como este:

private Context context; init(Context context){ this.context = context.getApplicationContext(); }

y recuerde llamar a esto para inicializar el singleton.

La diferencia entre el enfoque de aplicación y el enfoque de Singleton y por qué Singleton es mejor está en la documentación de la same functionality in a more modular way