Write the auto dictionary data to disk in a background thread to avoid blocking the UI thread.
Bug: 2536846 This also potentially fixes the occasional hangs on pressing space. Need to verify. Bug: 2509010main
parent
bad436e93b
commit
4ff60be170
|
@ -17,6 +17,8 @@
|
||||||
package com.android.inputmethod.latin;
|
package com.android.inputmethod.latin;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
@ -24,8 +26,8 @@ import android.database.Cursor;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
import android.database.sqlite.SQLiteQueryBuilder;
|
import android.database.sqlite.SQLiteQueryBuilder;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.provider.BaseColumns;
|
import android.provider.BaseColumns;
|
||||||
import android.provider.UserDictionary.Words;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,6 +53,9 @@ public class AutoDictionary extends ExpandableDictionary {
|
||||||
// Locale for which this auto dictionary is storing words
|
// Locale for which this auto dictionary is storing words
|
||||||
private String mLocale;
|
private String mLocale;
|
||||||
|
|
||||||
|
private HashMap<String,Integer> mPendingWrites = new HashMap<String,Integer>();
|
||||||
|
private final Object mPendingWritesLock = new Object();
|
||||||
|
|
||||||
private static final String DATABASE_NAME = "auto_dict.db";
|
private static final String DATABASE_NAME = "auto_dict.db";
|
||||||
private static final int DATABASE_VERSION = 1;
|
private static final int DATABASE_VERSION = 1;
|
||||||
|
|
||||||
|
@ -98,6 +103,7 @@ public class AutoDictionary extends ExpandableDictionary {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
|
flushPendingWrites();
|
||||||
mOpenHelper.close();
|
mOpenHelper.close();
|
||||||
super.close();
|
super.close();
|
||||||
}
|
}
|
||||||
|
@ -135,14 +141,29 @@ public class AutoDictionary extends ExpandableDictionary {
|
||||||
int freq = getWordFrequency(word);
|
int freq = getWordFrequency(word);
|
||||||
freq = freq < 0 ? addFrequency : freq + addFrequency;
|
freq = freq < 0 ? addFrequency : freq + addFrequency;
|
||||||
super.addWord(word, freq);
|
super.addWord(word, freq);
|
||||||
|
|
||||||
if (freq >= PROMOTION_THRESHOLD) {
|
if (freq >= PROMOTION_THRESHOLD) {
|
||||||
mIme.promoteToUserDictionary(word, FREQUENCY_FOR_AUTO_ADD);
|
mIme.promoteToUserDictionary(word, FREQUENCY_FOR_AUTO_ADD);
|
||||||
// Delete the word (for input locale) from the auto dictionary db, as it
|
freq = 0;
|
||||||
// is now in the user dictionary provider.
|
}
|
||||||
delete(COLUMN_WORD + "=? AND " + COLUMN_LOCALE + "=?",
|
|
||||||
new String[] { word, mLocale });
|
synchronized (mPendingWritesLock) {
|
||||||
} else {
|
// Write a null frequency if it is to be deleted from the db
|
||||||
update(word, freq, mLocale);
|
mPendingWrites.put(word, freq == 0 ? null : new Integer(freq));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules a background thread to write any pending words to the database.
|
||||||
|
*/
|
||||||
|
public void flushPendingWrites() {
|
||||||
|
synchronized (mPendingWritesLock) {
|
||||||
|
// Nothing pending? Return
|
||||||
|
if (mPendingWrites.isEmpty()) return;
|
||||||
|
// Create a background thread to write the pending entries
|
||||||
|
new UpdateDbTask(getContext(), mPendingWrites, mLocale).execute();
|
||||||
|
// Create a new map for writing new entries into while the old one is written to db
|
||||||
|
mPendingWrites = new HashMap<String, Integer>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,26 +207,49 @@ public class AutoDictionary extends ExpandableDictionary {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int delete(String where, String[] whereArgs) {
|
/**
|
||||||
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
|
* Async task to write pending words to the database so that it stays in sync with
|
||||||
int count = db.delete(AUTODICT_TABLE_NAME, where, whereArgs);
|
* the in-memory trie.
|
||||||
return count;
|
*/
|
||||||
}
|
private static class UpdateDbTask extends AsyncTask<Void, Void, Void> {
|
||||||
|
private final HashMap<String, Integer> mMap;
|
||||||
|
private final DatabaseHelper mDbHelper;
|
||||||
|
private final String mLocale;
|
||||||
|
|
||||||
private int update(String word, int frequency, String locale) {
|
public UpdateDbTask(Context context,
|
||||||
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
|
HashMap<String, Integer> pendingWrites, String locale) {
|
||||||
long count = db.delete(AUTODICT_TABLE_NAME, COLUMN_WORD + "=? AND " + COLUMN_LOCALE + "=?",
|
mMap = pendingWrites;
|
||||||
new String[] { word, locale });
|
mLocale = locale;
|
||||||
count = db.insert(AUTODICT_TABLE_NAME, null,
|
mDbHelper = new DatabaseHelper(context);
|
||||||
getContentValues(word, frequency, locale));
|
}
|
||||||
return (int) count;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ContentValues getContentValues(String word, int frequency, String locale) {
|
@Override
|
||||||
ContentValues values = new ContentValues(4);
|
protected Void doInBackground(Void... v) {
|
||||||
values.put(COLUMN_WORD, word);
|
SQLiteDatabase db = mDbHelper.getWritableDatabase();
|
||||||
values.put(COLUMN_FREQUENCY, frequency);
|
// Write all the entries to the db
|
||||||
values.put(COLUMN_LOCALE, locale);
|
Set<Entry<String,Integer>> mEntries = mMap.entrySet();
|
||||||
return values;
|
try {
|
||||||
|
for (Entry<String,Integer> entry : mEntries) {
|
||||||
|
Integer freq = entry.getValue();
|
||||||
|
db.delete(AUTODICT_TABLE_NAME, COLUMN_WORD + "=? AND " + COLUMN_LOCALE + "=?",
|
||||||
|
new String[] { entry.getKey(), mLocale });
|
||||||
|
if (freq != null) {
|
||||||
|
db.insert(AUTODICT_TABLE_NAME, null,
|
||||||
|
getContentValues(entry.getKey(), freq, mLocale));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
mDbHelper.close();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ContentValues getContentValues(String word, int frequency, String locale) {
|
||||||
|
ContentValues values = new ContentValues(4);
|
||||||
|
values.put(COLUMN_WORD, word);
|
||||||
|
values.put(COLUMN_FREQUENCY, frequency);
|
||||||
|
values.put(COLUMN_LOCALE, locale);
|
||||||
|
return values;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,7 @@ public class LatinIME extends InputMethodService
|
||||||
|
|
||||||
private UserDictionary mUserDictionary;
|
private UserDictionary mUserDictionary;
|
||||||
private ContactsDictionary mContactsDictionary;
|
private ContactsDictionary mContactsDictionary;
|
||||||
private ExpandableDictionary mAutoDictionary;
|
private AutoDictionary mAutoDictionary;
|
||||||
|
|
||||||
private Hints mHints;
|
private Hints mHints;
|
||||||
|
|
||||||
|
@ -562,6 +562,7 @@ public class LatinIME extends InputMethodService
|
||||||
if (mInputView != null) {
|
if (mInputView != null) {
|
||||||
mInputView.closing();
|
mInputView.closing();
|
||||||
}
|
}
|
||||||
|
if (mAutoDictionary != null) mAutoDictionary.flushPendingWrites();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue