Leggendo l’Android reference guide a proposito di android.app.Application, troviamo scritto:
Base class for those who need to maintain global application state. You can provide your own implementation by specifying its name in your AndroidManifest.xml’s <application> tag, which will cause that class to be instantiated for you when the process for your application/package is created.
There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way.
Sembra quindi il posto giusto, e piu’ elegante di un singleton, per mettere le nostre variabili globali quando non occorre fare cose troppo complicate e per inizializzarle al primo avvio dell’applicazione, mediante override del metodo OnCreate() della classe base. Qualcosa del genere:
La classe App.java
package it.rainbowbreeze.singleton;
public class App extends Application {
public static int myGlobalStaticValue;
public int myGlobalValue;
@Override
public void onCreate() {
super.onCreate();
myGlobalStaticValue = 10;
myGlobalValue = 20;
}
}
La modifica all’AndroidManifest.xml
E la chiamata da fare in un metodo qualunque di un’Activity, ad esempio:
//access to static field
int value = App.myGlobalStaticValue;
//access to non static fields
int value = ((App)context.getApplication()).myGlobalValue;
Da principio tutto funzionava, poi pero’ mi sono accorto di un problema non banale: che di tanto in tanto le variabili persistite in questo modo non mantengono il loro valore, soprattutto dopo che l’applicazione rimane in background per parecchio tempo o si fanno nel frattempo diverse altre cose col dispositivo.
Basito da questo comportamento, mi sono messo a cercare in giro, ed ecco che escono fuori le prime conferme, di cui riporto un estratto:
Consider a case – your app goes into the background because somebody is calling you (Phone app is in the foreground now). In this case && under some other conditions (check the above link for what they could be) the OS may kill your application process, including the Application subclass instance. As a result the state is lost. When you later return to the application, then the OS will restore its activity stack and Application subclass instance, however the myState field will be null.
This was an unplesant surprise for us in production. Believe me Android kills processes, it just depends on RAM state and other factors described in the documentation. It was a nightmare for us so I just share my real experience. Well we did not have this on emulators, but in real world some devices are ‘overloaded’ with apps, so killing a background process is a normal situation. Yes, if user then decides to get the app up into foreground – the OS restores its stack including the Application instance, however there will not be your static data you count on unless you persisted it.
In pratica, anche il contenuto dell’Application, come quello di ogni altro static singleton, puo’ venire ripulito dal sistema operativo. Come fare quindi per ovviare a questo problema?
Continue reading ‘android.app.Application, static singleton per variabili globali e NullPointerException’ »