2010-02-03 5 views
7

Estoy haciendo una aplicación para Android, en mi actividad necesito cargar una matriz de alrededor de 10000 cadenas. Cargando desde la base de datos fue lento, así que decidí ponerlo directamente en un archivo .java (como un campo privado). Tengo aproximadamente 20 de estas clases que contienen matrices de cadenas y mi pregunta es, ¿están todas las clases cargadas en la memoria después de que se inicia mi aplicación? Si es así, la Actividad en la que necesito estas cadenas se cargaría rápidamente, pero la aplicación como un todo tendría un inicio lento ... ¿Hay alguna otra manera, cómo cargar muy rápidamente una matriz de 10000 cadenas desde un archivo?¿Están todos los archivos .class en mi aplicación Java cargados en la memoria después del inicio de la aplicación?

ACTUALIZACIÓN: ¿Por qué necesito estas cadenas? Mi aplicación de Android te permite encontrar "viajes" en el transporte público de Praga: eliges la parada de salida, la parada de llegada y encuentra tu recorrido (mira here). Mi aplicación tiene una función de sugerencias: ingresa el carácter "c" como la parada de salida y aparece una sugerencia de ListView con paradas para comenzar con "c". Para estas sugerencias, necesito las cuerdas. La obtención de las sugerencias de la base de datos es lenta (alrededor de 400 ms en G1).

+0

¿Para qué sirven esas cadenas? – Macarse

+0

La mayoría de los dispositivos Android carecen de memoria principal, si es posible generaría esas cadenas sobre la marcha. –

+0

Si los muestra en una lista, un ListView + CursorAdapter los cargará sobre la marcha, muy rápidamente también. No debería tener ningún problema de rendimiento con SQLite en Android para un caso tan básico. –

Respuesta

4

En primer lugar, 400ms para realizar una consulta de base de datos simple es realmente lento. Tan lento que sospecho que hay algún problema en el esquema de su base de datos (por ejemplo, los índices) o la configuración de conexión de su base de datos.

Pero si un serio acerca de no usar una base de datos, hay un par de alternativas a lo que está haciendo actualmente:

  1. Disponer que las clases que contienen las matrices se cargan con pereza según sea necesario, utilizando Class.forName(...) . Si lo implementa correctamente, debería ser posible que el recolector de basura reclame las clases después de que se hayan cargado y las cadenas se hayan agregado a su estructura de datos primaria.

  2. Convierte las 10000 cadenas en un archivo plano, coloca el archivo en el archivo JAR de la aplicación. Luego use Class.getResourceAsStream(...) para abrir el archivo y leerlo en la matriz en memoria.

  3. Como anteriormente, pero usando un archivo indexado y reemplazando la matriz con una estructura de datos que le permite leer Cadenas del archivo perezosamente. (Esto será un poco complicado, pero si le preocupa la memoria consumida por las 10000 Strings, esto ayudará a solucionarlo.)

+0

Gracias, ahora estoy usando Class.forName ("") y es muy rápido. – fhucho

3

Una clase se carga solo cuando se hace referencia por primera vez.

Aunque necesita una matriz de 10000, es posible que no necesite todos a la vez. Aquí es donde entra el concepto de paginación. Este enlace indica que Paging is often done in Android .Inicialmente solo tiene una pequeña cantidad de matriz en la memoria, y cuando la necesite, siga cargándola en la memoria y descargando cualquier dato anterior de la memoria si no lo desea.

Por ej. en cualquier tabla, de una sola vez, el usuario puede ver como máximo 50 registros, luego tendrá que desplazarse (teniendo en cuenta que su pantalla no tiene el tamaño de iMax movie theatre). Cuando se desplaza, carga el siguiente fragmento de datos y descarga cualquier información que ahora no sea posible para el usuario.

+0

Lamentablemente necesito todos los 10000 (vea la pregunta actualizada). Entonces, si tengo el nombre de la clase en algún lugar de mi código de Actividad, ¿JVM cargará la clase cuando se inicie mi Actividad? – fhucho

+0

@fhucho - sí, lo haría. –

+0

No estoy seguro acerca de Android, pero el sol JVM hace la carga lenta. La clase se inicializará cuando se use por primera vez. por ejemplo, la primera vez que algún código utiliza un valor estático de la clase o llama a nuevo en él. Solo importarlo no hace nada y si no se llama a NEW o MyClass.staticMethod() en su ruta de ejecución, entonces nunca se carga. –

1

¿Cuándo es un tipo cargado? Esta es una pregunta sorprendentemente difícil a respuesta. Esto se debe en gran parte a la significativa flexibilidad que ofrece, por las especificaciones de JVM, a las implementaciones de JVM . La carga debe ser realizada antes de vincular y vincular debe realizarse antes de la inicialización . La especificación VM hace estipula el tiempo de inicialización . Requiere estrictamente que un tipo se inicie en su primer uso activo (consulte el Apéndice A para obtener una lista de lo que constituye un "uso activo "). Esto significa que la carga (y el enlace ) de un tipo DEBE realizarse en o antes del primer uso activo de ese tipo .

De http://www.developer.com/java/other/article.php/2248831/Java-Class-Loading-The-Basics.htm

0

no creo que va a ser feliz con el mantenimiento de 10K Cuerdas, codificada en los archivos Java.

Basta con comprobar si está utilizando la base de datos correcta para su problema y si sus índices están configurados correctamente. Un índice incorrecto puede causar un rendimiento realmente pobre.

Además, debe limitar la cantidad de resultados devueltos por la consulta, pero asegúrese de no recuperar las entradas una por una.

Si nada se ajusta, aún puede precargar las cadenas de la base de datos al inicio.

Puede precargar, digamos 10 entradas, para cada personaje. Si un personaje está ingresado, puede precargar las entradas con ese personaje después de otro, y así sucesivamente.

Cuestiones relacionadas