¿Cuándo / por qué se destruye mi instancia de singleton de Java?

Tengo una aplicación para Android que está configurada para iniciar una actividad de Java (llamada MyJavaActivity), que a su vez lanza una NativeActivity. Cuando la NativeActivity termina, regresa a MyJavaActivity.

También tengo una clase singleton de Java (lo llamo MyJavaSingleton) que me gustaría permanecer en la memoria durante el ciclo de vida de mi aplicación. Establecer algunas de las variables de la clase singleton de mi NativeActivity (utilizando JNI), que puede ser recuperado más tarde por MyJavaActivity.

El problema es que la instancia de MyJavaSingleton parece estar en la memoria hasta que NativeActive salga, pero de alguna manera parece que se vuelve a establecer null de nuevo cuando MyJavaActivity se inicia de nuevo, por lo que todas las variables que había establecido en NativeActivity ahora se restablecen a sus valores predeterminados. ¿Por qué pasó esto?

public class MyJavaActivity extends Activity implements View.OnTouchListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MyJavaSingleton.Instance().DoStuff(); } @Override public boolean onTouch(View arg0, MotionEvent arg1) { Intent intent = new Intent(MyJavaActivity.this, NativeActivity.class); startActivity(intent); // at this point, android_main will be executed } } ///////////////////////////// public class MyJavaSingleton { static private MyJavaSingleton mInstance = null; synchronized public static MyJavaSingleton Instance() { if( mInstance == null ) { mInstance = new MyJavaSingleton(); Log.v(TAG, "New MyJavaSIngleton instance"); } return mInstance; } } ///////////////////////////// // Native void android_main(struct android_app* state) { // Do various stuff, set some variables on the MyJavaSingleton // At this point, MyJavaSingleton.mInstance is still at the same address in memory, which is good // ANativeActivity_finish(state->activity); exit(0); // Problem: sometime after this exit and before MyJavaActivity::onCreate is called, MyJavaSingleton.mInstance is set to null! } 

En la extracción de código anterior, "Nueva instancia de MyJavaSIngleton" se imprime cuando se inicia la aplicación, y luego de nuevo justo después de que las salidas de NativeActivity (es decir, después de que android_main se salga) y onCreate de MyJavaActivity se vuelva a llamar.

¿Por qué MyJavaSingleton.mInstance se vuelve NULL al volver a ingresar a MyJavaActivity?

Cada aplicación de Android se ejecuta en su propio proceso, siempre y cuando siga funcionando, su Singleton estará disponible. Cuando el proceso muere, su singleton se pierde. Por lo tanto, cuando la aplicación se vuelve a lanzar este objeto singleton tendrá que volver a crear.

Asegúrese de leer la documentación sobre el ciclo de vida del proceso:

http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html#Lifecycle

En este caso, siempre que su aplicación esté en segundo plano (en términos de actividades, ninguna de sus actividades es visible para el usuario), su proceso puede ser eliminado en cualquier momento. Si el usuario vuelve más tarde a una de sus actividades, se creará un nuevo proceso y se creará una nueva instancia de la actividad.

Haría que mInstance fuera privada. Sólo en caso de algún otro código se establece accidentalmente.

"Android OS puede y va a terminar su singleton y ni siquiera decirle al respecto."

Fuente: http://www.2linessoftware.com/2010/08/03/singletons-and-services-and-shutdowns-oh-my/

El autor de ese artículo sugiere algunas soluciones, como el uso de un servicio o la subclase de la clase de aplicación. Parece que hay un poco de apoyo para este último:

Cómo declarar variables globales en Android?

  • Acceso al objeto GoogleApiClient en Todas las actividades
  • ¿Es necesario guardar singletons?
  • Android MediaPlayer Singleton
  • Ciclo de vida de aplicaciones Android y singelton
  • Android: una vs muchas instancias de HttpClient por aplicación
  • Android: ¿Cómo acceder a una sola base de datos de múltiples actividades en la aplicación?
  • Singletons no disponibles cuando la aplicación vuelve a la memoria
  • El servicio de Android no funciona como singleton
  • Acceder a los campos singleton mediante un método estático
  • ¿Cuál es la diferencia entre "nuevo A ()" y "A.newInstance ()"?
  • Android Singleton con un contexto global
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.