2010-10-21 4 views
7

Todo,Android NDK: cómo limpiar el código nativo después de reiniciar la actividad?

Soy consciente de que, de forma predeterminada, una actividad se eliminará y se reiniciará cuando cambie la orientación de la pantalla o cuando se deslice hacia adentro o hacia afuera. (Ver Activity restart on rotation Android). Mi pregunta es, ¿cuál es la forma correcta de manejar esto desde una perspectiva de código nativo? p.ej. si tengo un bloque estático cargando una biblioteca nativa y mi aplicación se reinicia, ¿cómo me aseguro de que cualquier memoria en la tierra nativa se trate de manera adecuada? El problema es

Cuando hacemos girar el dispositivo, se ve como un conjunto de subprocesos por separado se crea y los antiguos no se eliminan. Esto significa que cada vez que alguien gira el dispositivo, tenemos una tonelada más hilos sentados sin hacer nada y tomando memoria

¿Cómo puedo garantizar que esto no suceda? Veo en los JNIExample page algunas notas en la parte inferior:

[*] Los problemas no resueltos y los insectos Incluso aunque el ejemplo es totalmente funcional, hay un par problemas que quedan por resolver, que no era capaz de averiguar hasta ahora. Los problemas aparecen cuando inicia la actividad , luego presiona el botón Atrás para ocultarlo, y luego lo vuelve a iniciar. En mi experiencia, las llamadas a las funciones nativas en dicha actividad reiniciada fallarán espectacularmente. callVoid() simplemente se bloquea con un error de segmentación , mientras que las llamadas a getNewData() y getDataString() causa JVM para abortar con un error, porque ya no es contento con el caché a nivel mundial referencia de objeto. Parece que la actividad reinicio de alguna manera se pierde el caché referencias a objetos, a pesar de que están protegidas con NewGlobalRef(), y la actividad se está ejecutando dentro del JVM originales (reinicio actividad no no quiere decir que la propia JVM está renovadas) . No tengo una buena explicación de sobre por qué sucede eso, así que si tiene alguna idea, , déjeme saber .

¿Se ha solucionado esto?

Respuesta

6

Reiniciar en Android NDK es molesto. Todos los datos estáticos que tiene permanecen, porque reutiliza el proceso, por lo que debe restablecer manualmente todo lo que no será válido en una nueva ejecución (como cualquier textura OpenGL o objetos de búfer de vértice).También le ofrece un nuevo subproceso de Java y una nueva aplicación Java y otros objetos, por lo que las referencias globales en caché a los objetos que serían nuevos en una nueva instancia de su aplicación también deben borrarse.

Así que la estrategia que uso es doble: minimice los reinicios y nukee todo al reiniciar.

Minimiza los reinicios mediante el manejo de configChanges en la aplicación, como se dice en la respuesta a la pregunta que ha vinculado. Luego, al abrir un teclado o al rotar no se reinicia la aplicación, que es como debería ser para cualquier aplicación con tiempos de inicio no triviales.

Y cuando detecto que una nueva instancia de mi aplicación ha comenzado, publico todo lo crítico de la instancia anterior en ese momento, incluyendo la liberación de cualquier objeto Java que tenga a través de NewGlobalRef. Traté de minimizar los datos estáticos, pero los pocos lugares inevitables donde guardo los objetos estáticos los borro cuando detecto la nueva instancia que se inicia.

Los hilos antiguos deberían desaparecer una vez que no haya más referencias destacadas (es decir, una vez que haya lanzado todos sus objetos NewGlobalRef).

2

Si la máquina virtual se reinicia, usted comienza desde cero. Si no, el estado está justo donde lo dejó. No hay invalidación de referencias de objetos en caché que extraiga cosas de NewGlobalRef. Escribí algunas otras notas sobre el artículo wooyd on the NDK mailing list.

Si tiene que inicializar datos cuando se reinicia su actividad, debe agregar una llamada de inicialización explícita a su actividad (en onCreate, creo). Asegúrate de descartar correctamente todo lo que retuviste de la ronda anterior - DeleteLocalRef luego almacena NULL, no solo memset() a cero.

Cuestiones relacionadas