将JSON字符串解析为SQLite表的最快方法是什么?

sim*_*ick 6 sqlite android json gson sqliteopenhelper

我正在编写一个Android应用程序,偶尔需要下载大约1MB的json字符串并包含大约1000个元素,并将其中的每一个解析为SQLite数据库,我用它来填充ListActivity.

即使下载和解析不是每次与应用程序交互时都需要完成的事情(仅在第一次运行时或用户选择刷新数据时),我仍然担心解析部分需要花费太长时间,在大约两到三分钟 - 在手机应用程序条款似乎是永恒!

我目前正在使用Gson将每个json对象解析为我定义的自定义对象,然后使用SQLiteOpenHelper将其输入数据库.

我的问题是 - 有更快的方法来实现这个吗?如果不使用Gson,直接与json交互会明显更快吗?或者我在下面的代码中做了一些愚蠢的事情,这会让事情变慢?

这是我在AsyncTask中使用的方法将json解析为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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的VegDataHandler类的addCompany方法,它扩展了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();
}
Run Code Online (Sandbox Code Playgroud)

这是在添加到SQLite之前保存每个json元素的类(为简洁起见,我省略了getters和setter).

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;

}
Run Code Online (Sandbox Code Playgroud)

提前感谢您的回复.

NuS*_*ler 5

首先,您需要确定最耗时的过程部分.从上面的评论来看,听起来像JSON解析是罪魁祸首.

如果JSON解析是问题:
研究并考虑更快的JSON解析器.也许像json-smart这样的东西.

如果问题是SQLite/DB批量插入:
请参阅我的答案

一般提示:

  • 尽可能地回收对象(保持的最小化)
  • 始终至少在数据库批量插入中使用事务
  • 不要打开/关闭数据库.在处理的开始/结束时执行一次
  • 使用预编译的语句!