简体   繁体   中英

Slow Performance on Android implementing Offline Dictionary using JsonReader

I am trying to implement an offline dictionary in a ebook reader app I am working on.

Let me explain the process. The dictionary is not part of the original app, rather will be downloaded in background. The original dictionary data is a json of 24MB long that is later reduced to 6MB upon compression.

I then download the compressed json and extract it on device. The dictionary json has around 150,000 entires that I am saving in a DB. I am using JsonReader to parse the json sequently, adding each entry in DB.

Below is the code for reading the json, parsing each entry and saving it in a DB (I hope it's self explanatory)

public void readFile() throws IOException {

    File jsonInputFile = new File(DownloadClassHelper.getOfflineDictionaryDownloadPath());

    InputStream inputStream = new FileInputStream(jsonInputFile);
    JsonReader reader = new JsonReader(new InputStreamReader(inputStream, "UTF-8"));

    try {
        readArray(reader);
    } finally {
        reader.close();
    }
}

public void readArray(JsonReader reader) throws IOException {

    reader.beginArray();
    while (reader.hasNext()) {
        readObject(reader);
    }
    reader.endArray();
}

public void readObject(JsonReader reader) throws IOException {

    String word = null;

    reader.beginObject();
    while (reader.hasNext()) {
        String name = reader.nextName();
        if (name.equals("word")) {
            word = reader.nextString();
        } else if (name.equals("meanings") && reader.peek() != JsonToken.NULL) {
            readMeaningsArray(word, reader);
        } else {
            reader.skipValue();
        }
    }
    reader.endObject();
}

public void readMeaningsArray(String word, JsonReader reader) throws IOException {

    reader.beginArray();
    while (reader.hasNext()) {
        readMeaningObject(word, reader);
    }
    reader.endArray();
}

public void readMeaningObject(String word, JsonReader reader) throws IOException {

    String definition = null, pos = null;

    reader.beginObject();
    while (reader.hasNext()) {
        String name = reader.nextName();

        if (name.equals("definition")) {
            definition = reader.nextString();
        } else if (name.equals("pos")) {
            pos = reader.nextString();
        } else {
            reader.skipValue();
        }

    }
    reader.endObject();

    addWord(word, definition, pos);

    Log.d(TAG, word + " | " + definition + " | " + pos);
}

/**
 * Add a word to the dictionary.
 * @return true or false if failed
 */
public boolean addWord(String word, String definition, String pos) {

    ContentValues initialValues = new ContentValues();
    initialValues.put(TableDictionary.COLUMN_WORD, word);
    initialValues.put(TableDictionary.COLUMN_DEFINITION, definition);
    initialValues.put(TableDictionary.COLUMN_POS, pos);

    return CPWrapper.insert(TableDictionary.TABLE_NAME, initialValues);
}

I am facing performance issue with my current approach since it is taking close to 30 minutes to parse the entire json.

What is the ideal method for implementing offline dictionary in Android apps? Do I need to change my current approach? If yes, then how should I ideal implement such system in android.

Any recommendations/tips are highly welcomed.

The best ways is using a prepopulated database for your application. So, instead downloading the JSON file, you can add the database file to your apk in the assets folder. You can use Android SQLiteAssetHelper

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM