Xamarin ¿Qué sucede con el singleton inicializado de manera perezosa después de que la aplicación se va al segundo plano?
Uso de inicialización diferida para singleton de aplicación en Xamarin.Forms (la aplicación se ejecuta en iOS):
public sealed class DataSingleton
{
private static readonly Lazy<datasingleton> lazy = new Lazy<datasingleton>(() => new DataSingleton(), LazyThreadSafetyMode.PublicationOnly); // también intenté sin el segundo parámetro
public static DataSingleton Instance
{
get { return lazy.Value; }
}
...
}
Y lo llamo en el servidor web que se ejecuta para proporcionar datos al front-end que está en Angular (uso una vista web para mostrar el código de Angular):
var server = new WebServer(o => o
.WithUrlPrefix($"http://localhost:{appSettings.ApiPort}")
.WithMode(HttpListenerMode.EmbedIO))
.WithCors()
.WithLocalSessionManager()
.WithWebApi("/api", m => m
.WithController<testcontroller>()
.WithController<settingscontroller>()
.WithController<reportcontroller>()
.WithController<systemcontroller>())
.WithModule(new ActionModule("/", HttpVerbs.Any,
ctx => ctx.SendDataAsync(new { Message = "Error" })))
.RunAsync();
En los controladores se llama a DataSingleton para obtener/establecer datos, pero después de que la aplicación vuelva del segundo plano, DataSingleton.Instance
es nulo.
¿Qué debo hacer para no perder los datos del singleton mientras la aplicación está en segundo plano durante poco tiempo (aproximadamente 5 minutos)?
Actualización: Me he dado cuenta de que este problema solo ocurre en los controladores, porque cuando la aplicación vuelve a primer plano, puedo ver todos los datos en el evento
WillEnterForeground
de AppDelegate.
davy.ai
Para evitar perder datos de un singleton cuando la aplicación está en segundo plano durante un corto período de tiempo, puedes utilizar los eventos del ciclo de vida de la aplicación en Xamarin.iOS para persistir y restaurar el objeto singleton.
Primero, puedes agregar controladores de eventos para los eventos
DidEnterBackground
yWillEnterForeground
en tu claseAppDelegate
:En el controlador de eventos
DidEnterBackground
, puedes guardar los datos relevantes del objeto singleton en un almacenamiento persistente, comoNSUserDefaults
o una base de datos SQLite. Luego, en el controlador de eventosWillEnterForeground
, puedes restaurar los datos desde el almacenamiento hacia el objeto singleton.Alternativamente, si solo necesitas persistir el objeto singleton temporalmente (es decir, durante el tiempo en que la aplicación está en segundo plano), puedes serializar el objeto en un arreglo de bytes y guardarlo en
NSUserDefaults
utilizandoNSData
:Ten en cuenta que en este ejemplo,
DataSingleton
necesita ser serializable (es decir, marcado con el atributo[Serializable]
). Además, la claseDataSingleton
necesita tener un constructor por defecto (es decir, un constructor sin parámetros) para que la deserialización funcione.