¿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.
- Obtener contexto en la biblioteca de Android
- Los datos estáticos guardados dentro de singleton son nulos a veces cuando se vuelve a la aplicación desde el fondo
- Android: Mejor manera de guardar los datos almacenados en la clase Application Singleton
- Fragmento no UI vs Singleton
- Java.lang.IllegalStateException: La aplicación PagerAdapter cambió el contenido del adaptador sin llamar a PagerAdapter # notifyDataSetChanged android
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?
- Singleton con contexto en Android
- Métodos estáticos o singleton, ¿cuál elegir?
- Android: No se puede realizar esta operación porque se ha cerrado el grupo de conexiones
- ¿Puedo obtener cierta eficiencia al declarar a los miembros apropiados "estáticos" en la actividad de Android?
- ¿Puede el recolector de basura desasignar una instancia singleton? (Y por qué o cómo evitarlo)
- Cómo pasar el contexto de la aplicación dentro Singleton y SharedPreferences Clases
- SQLite incapaz de abrir el archivo de base de datos (código 14) en la consulta "SELECT" frecuente
- Configuración del valor de propiedad Singleton en el Listado de Firebase
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?
- Verificación de facturación de Android en la aplicación
- ¿Algún problema o problema significativo con la Biblioteca de Databinding de Android?