Creación de una base de datos de aplicaciones para Android con gran cantidad de datos

La base de datos de mi aplicación necesita ser llenado con una gran cantidad de datos, por lo que durante onCreate() , no es sólo algunas instrucciones de crear tabla sql, hay un montón de inserciones. La solución que elegí es almacenar todas estas instrucciones en un archivo sql ubicado en res / raw y que está cargado con Resources.openRawResource(id) .

Funciona bien pero me enfrento al problema de codificación, tengo algunos caharacters acentuados en el archivo sql que aparece mal en mi aplicación. Este mi código para hacer esto:

 public String getFileContent(Resources resources, int rawId) throws IOException { InputStream is = resources.openRawResource(rawId); int size = is.available(); // Read the entire asset into a local byte buffer. byte[] buffer = new byte[size]; is.read(buffer); is.close(); // Convert the buffer into a string. return new String(buffer); } public void onCreate(SQLiteDatabase db) { try { // get file content String sqlCode = getFileContent(mCtx.getResources(), R.raw.db_create); // execute code for (String sqlStatements : sqlCode.split(";")) { db.execSQL(sqlStatements); } Log.v("Creating database done."); } catch (IOException e) { // Should never happen! Log.e("Error reading sql file " + e.getMessage(), e); throw new RuntimeException(e); } catch (SQLException e) { Log.e("Error executing sql code " + e.getMessage(), e); throw new RuntimeException(e); } 

La solución que encontré para evitar esto es cargar las instrucciones sql de una static final String enorme en lugar de un archivo, y todos los caracteres acentuados aparecen bien.

¿Pero no hay una manera más elegante de cargar las instrucciones del sql que un atributo grande de static final String con todas las instrucciones del sql?

Creo que su problema está en esta línea:

 return new String(buffer); 

Estás convirtiendo la matriz de bytes en un java.lang.String pero no estás diciendo a Java / Android que la codificación de usar. Así que los bytes para sus caracteres acentuados no se están convirtiendo correctamente como la codificación incorrecta se está utilizando.

Si utiliza el constructor String(byte[],<encoding>) , puede especificar la codificación que tiene su archivo y sus caracteres se convertirán correctamente.

La solución de archivos SQL parece perfecta, es sólo que usted necesita para asegurarse de que el archivo se guarda en la codificación utf8 de lo contrario todos los caracteres acentuados se perderán. Si no desea cambiar la codificación del archivo, debe pasar un argumento adicional a la nueva String(bytes, charset) define la codificación del archivo.

No prefieren utilizar recursos de archivo en lugar de static final String para evitar tener todos los bytes innecesarios cargado en la memoria. En los teléfonos móviles que desea guardar toda la memoria posible!

Estoy utilizando un enfoque diferente: En lugar de ejecutar cargas de sentencias SQL (que tardará mucho tiempo en completarse), construir mi base de datos sqlite en el escritorio, ponerlo en la carpeta de activos, crear un sqlite db vacío en android y copiar el Db de la carpeta assets a la carpeta de la base de datos. Este es un enorme aumento en la velocidad. Tenga en cuenta que primero debe crear una base de datos vacía en android y, a continuación, puede copiarla y sobrescribirla. De lo contrario, Android no le permitirá escribir un db en la carpeta de bases de datos. Hay varios ejemplos en Internet. BTW, parece que este enfoque funciona mejor, si el DB no tiene extensión de archivo.

Parece que estás pasando todas tus sentencias de sql en una cadena. Eso es un problema porque execSQL espera "una sola sentencia que no es una consulta" (ver documentación [aquí] [1]). Lo que sigue es una solución algo fea pero que trabaja.

Tengo todas mis declaraciones sql en un archivo como este:

INSERT INTO table1 VALORES (1, 2, 3);

INSERT INTO tabla1 VALORES (4, 5, 6);

INSERT INTO tabla1 VALORES (7, 8, 9);

Observe las nuevas líneas entre el texto (punto y coma seguido por 2 nuevas líneas) Entonces, hago esto:

 String text = new String(buffer, "UTF-8"); for (String command : text.split(";\n\n")) { try { command = command.trim(); //Log.d(TAG, "command: " + command); if (command.length() > 0) db.execSQL(command.trim()); } catch(Exception e) {do whatever you need here} 

Mis columnas de datos contienen blobs de texto con nuevas líneas y puntos y coma, así que tuve que encontrar un separador de comandos diferente. Sólo asegúrese de ser creativo con la división de str: utilizar algo que sabe que no existe en sus datos.

HTH Gerardo

[1]: http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#execSQL(java.lang.String , java.lang.Object [])

  • Archivo .gitignore típico de una aplicación para Android
  • Android, envío de un mensaje de voz
  • Error: Error de ejecución para la tarea ': app: shrinkReleaseMultiDexComponents'
  • La conversión al formato de Dalvik falló con el error 1 puesto que el SDK de Facebook
  • Dispositivo Android (excepto la nota de galaxia 2) no puede obtener paquetes UDP
  • Ciclo de vida de las aplicaciones de Android y uso de
  • ¿Cómo puedo implementar un AsyncTaskLoader simple?
  • Bouncycastle codificación de la curva elíptica en Android
  • Variables de String de paso por referencia a setOnItemSelectedListener de varios Spinners
  • ¿Es posible saltar la pista de una aplicación de Android?
  • Cómo establecerLayoutParams en elementos añadidos dinámicamente en Widget
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.