2012-05-31 35 views
6

Estoy escribiendo una aplicación de Android que de vez en cuando tendrá que descargar una cadena json de alrededor de 1MB y que contiene alrededor de 1000 elementos, y analizar cada uno de estos en una base de datos SQLite, que utilizo para rellenar una ListActivity.¿Cuál es la forma más rápida de analizar una cadena JSON en una tabla SQLite?

Aunque la descarga y el análisis no es algo que deba hacerse en cada interacción con la aplicación (solo en la primera ejecución o cuando el usuario elige actualizar los datos), todavía me preocupa que la parte de análisis está tardando demasiado, alrededor de dos o tres minutos, ¡parece una eternidad en términos de la aplicación telefónica!

Actualmente estoy usando Gson para analizar cada objeto json en un objeto personalizado que he definido, y luego usar un SQLiteOpenHelper para ingresarlo en la base de datos.

Mi pregunta es: ¿hay una forma más rápida de implementar esto? ¿Sería notablemente más rápido interactuar con el json directamente, sin usar Gson? ¿O estoy haciendo algo estúpido en el siguiente código que está ralentizando las cosas?

Aquí es el método que estoy usando en mi AsyncTask para analizar el JSON a SQLite:

protected Boolean doInBackground(Integer... bType) { 

    InputStream source = getJsonInputStream(bTypeString); 

    VegDataHandler db = new VegDataHandler(mainActivity, bTypeString); 
    Gson gson = new Gson(); 
    Reader reader = new InputStreamReader(source); 

    JsonParser jParser = new JsonParser(); 
    JsonArray jArray = jParser.parse(reader).getAsJsonArray(); 

    aLength = jArray.size(); 
    mCurrProgress = 1; 
    publishProgress(mCurrProgress, 0, aLength); 

    /* Each array element is of the form { company: {...} } */ 
    int i = 0; 
    mCurrProgress = 2; 
    for (JsonElement obj : jArray) { 
     Company c = gson.fromJson(obj.getAsJsonObject().getAsJsonObject("company"), Company.class); 
     db.addCompany(c); 
     i++; 
     publishProgress(mCurrProgress, i); 
    } 
} 

Este es el método addCompany de mi clase VegDataHandler, que se extiende SQLiteOpenHelper:

public void addCompany(Company c) { 
    SQLiteDatabase db = this.getWritableDatabase(); 
    ContentValues values = new ContentValues(); 
    values.put(KEY_ID, c.getCompanyId()); 
    values.put(KEY_NAME, c.getCompanyName()); 
    values.put(KEY_RYG, c.getCompanyRedYellowGreen()); 
    values.put(KEY_COUNTRY, c.getCompanyCountry()); 
    values.put(KEY_URL, c.getCompanyUrl()); 
    values.put(KEY_NOTES, c.getCompanyNotes()); 
    values.put(KEY_EMAIL, c.getCompanyEmail()); 
    db.insertWithOnConflict(TABLE_COMPANY, null, values, SQLiteDatabase.CONFLICT_REPLACE); 
    db.close(); 
} 

Este es la clase que contiene cada elemento json antes de agregar al SQLite (he omitido los getters y setters para abreviar).

public class Company { 

    public Company() { 
    } 

    @SerializedName("id") 
    public int companyId; 

    @SerializedName("company_name") 
    public String companyName; 

    @SerializedName("red_yellow_green") 
    public String companyRedYellowGreen; 

    @SerializedName("country") 
    public String companyCountry; 

    @SerializedName("url") 
    public String companyUrl; 

    @SerializedName("notes") 
    public String companyNotes; 

    @SerializedName("email") 
    public String companyEmail; 

} 

Gracias de antemano por cualquier respuesta.

+0

¿Ha intentado aislar el motivo del retraso, ya sea la descarga que lleva tiempo o el análisis? – Rajesh

+0

¿Desea agregar registros masivos en la base de datos? –

+0

@Rajesh - definitivamente es el análisis el que más tiempo lleva. Estoy usando el método publishProgress() para mostrar en qué etapa de descarga/análisis/inflado está. – simick

Respuesta

4

Primero debe determinar la (s) porción (es) del proceso que están consumiendo la mayor cantidad de tiempo. De su comentario anterior, parece que el análisis JSON es el culpable.

Si JSON análisis es la cuestión:
Investigación y considerar un analizador JSON más rápido. Tal vez algo así como json-smart.

Si las inserciones SQLite/DB son el tema:
See my answer here

consejos generales:

  • reciclaje objetos tanto como sea posible (mantener nueva al mínimo)
  • Utilice siempre las transacciones en inserciones masivas de BD al menos
  • No abrir/cerrar la base de datos. Haga esto una vez al inicio/finalización de su procesamiento
  • ¡Use declaraciones precompiladas!
+0

Esto es genial, muchas gracias por los consejos. Investigaré tanto las inserciones masivas de json-smart como las de DB para ver si puedo ahorrar segundos más valiosos. – simick

Cuestiones relacionadas