Cache three main keyboards to improve average switch time
This typically improves the average loading time by about 35%, after the first time. Bug: 8689779 Change-Id: I7b0ab6b942af1d3250b9dcbf875f27f9f64692f3main
parent
8ea77542f9
commit
4d8f9f1cab
|
@ -80,6 +80,14 @@ public final class KeyboardLayoutSet {
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final Params mParams;
|
private final Params mParams;
|
||||||
|
|
||||||
|
// How many layouts we forcibly keep in cache. This only includes ALPHABET (default) and
|
||||||
|
// ALPHABET_AUTOMATIC_SHIFTED layouts - other layouts may stay in memory in the map of
|
||||||
|
// soft-references, but we forcibly cache this many alphabetic/auto-shifted layouts.
|
||||||
|
private static final int FORCIBLE_CACHE_SIZE = 4;
|
||||||
|
// By construction of soft references, anything that is also referenced somewhere else
|
||||||
|
// will stay in the cache. So we forcibly keep some references in an array to prevent
|
||||||
|
// them from disappearing from sKeyboardCache.
|
||||||
|
private static final Keyboard[] sForcibleKeyboardCache = new Keyboard[FORCIBLE_CACHE_SIZE];
|
||||||
private static final HashMap<KeyboardId, SoftReference<Keyboard>> sKeyboardCache =
|
private static final HashMap<KeyboardId, SoftReference<Keyboard>> sKeyboardCache =
|
||||||
CollectionUtils.newHashMap();
|
CollectionUtils.newHashMap();
|
||||||
private static final KeysCache sKeysCache = new KeysCache();
|
private static final KeysCache sKeysCache = new KeysCache();
|
||||||
|
@ -110,6 +118,7 @@ public final class KeyboardLayoutSet {
|
||||||
boolean mNoSettingsKey;
|
boolean mNoSettingsKey;
|
||||||
boolean mLanguageSwitchKeyEnabled;
|
boolean mLanguageSwitchKeyEnabled;
|
||||||
InputMethodSubtype mSubtype;
|
InputMethodSubtype mSubtype;
|
||||||
|
boolean mIsSpellChecker;
|
||||||
int mOrientation;
|
int mOrientation;
|
||||||
int mKeyboardWidth;
|
int mKeyboardWidth;
|
||||||
int mKeyboardHeight;
|
int mKeyboardHeight;
|
||||||
|
@ -185,7 +194,18 @@ public final class KeyboardLayoutSet {
|
||||||
elementParams.mProximityCharsCorrectionEnabled);
|
elementParams.mProximityCharsCorrectionEnabled);
|
||||||
keyboard = builder.build();
|
keyboard = builder.build();
|
||||||
sKeyboardCache.put(id, new SoftReference<Keyboard>(keyboard));
|
sKeyboardCache.put(id, new SoftReference<Keyboard>(keyboard));
|
||||||
|
if ((id.mElementId == KeyboardId.ELEMENT_ALPHABET
|
||||||
|
|| id.mElementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED)
|
||||||
|
&& !mParams.mIsSpellChecker) {
|
||||||
|
// We only forcibly cache the primary, "ALPHABET", layouts.
|
||||||
|
for (int i = sForcibleKeyboardCache.length - 1; i >= 1; --i) {
|
||||||
|
sForcibleKeyboardCache[i] = sForcibleKeyboardCache[i - 1];
|
||||||
|
}
|
||||||
|
sForcibleKeyboardCache[0] = keyboard;
|
||||||
|
if (DEBUG_CACHE) {
|
||||||
|
Log.d(TAG, "forcing caching of keyboard with id=" + id);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (DEBUG_CACHE) {
|
if (DEBUG_CACHE) {
|
||||||
Log.d(TAG, "keyboard cache size=" + sKeyboardCache.size() + ": "
|
Log.d(TAG, "keyboard cache size=" + sKeyboardCache.size() + ": "
|
||||||
+ ((ref == null) ? "LOAD" : "GCed") + " id=" + id);
|
+ ((ref == null) ? "LOAD" : "GCed") + " id=" + id);
|
||||||
|
@ -272,6 +292,11 @@ public final class KeyboardLayoutSet {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder setIsSpellChecker(final boolean isSpellChecker) {
|
||||||
|
mParams.mIsSpellChecker = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder setOptions(final boolean voiceKeyEnabled, final boolean voiceKeyOnMain,
|
public Builder setOptions(final boolean voiceKeyEnabled, final boolean voiceKeyOnMain,
|
||||||
final boolean languageSwitchKeyEnabled) {
|
final boolean languageSwitchKeyEnabled) {
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
|
@ -422,7 +447,8 @@ public final class KeyboardLayoutSet {
|
||||||
final InputMethodSubtype subtype =
|
final InputMethodSubtype subtype =
|
||||||
AdditionalSubtype.createAdditionalSubtype(locale, layout, null);
|
AdditionalSubtype.createAdditionalSubtype(locale, layout, null);
|
||||||
return createKeyboardSet(context, subtype, SPELLCHECKER_DUMMY_KEYBOARD_WIDTH,
|
return createKeyboardSet(context, subtype, SPELLCHECKER_DUMMY_KEYBOARD_WIDTH,
|
||||||
SPELLCHECKER_DUMMY_KEYBOARD_HEIGHT, false);
|
SPELLCHECKER_DUMMY_KEYBOARD_HEIGHT, false /* testCasesHaveTouchCoordinates */,
|
||||||
|
true /* isSpellChecker */);
|
||||||
}
|
}
|
||||||
|
|
||||||
@UsedForTesting
|
@UsedForTesting
|
||||||
|
@ -442,18 +468,20 @@ public final class KeyboardLayoutSet {
|
||||||
throw new RuntimeException("Orientation should be ORIENTATION_LANDSCAPE or "
|
throw new RuntimeException("Orientation should be ORIENTATION_LANDSCAPE or "
|
||||||
+ "ORIENTATION_PORTRAIT: orientation=" + orientation);
|
+ "ORIENTATION_PORTRAIT: orientation=" + orientation);
|
||||||
}
|
}
|
||||||
return createKeyboardSet(context, subtype, width, height, testCasesHaveTouchCoordinates);
|
return createKeyboardSet(context, subtype, width, height, testCasesHaveTouchCoordinates,
|
||||||
|
false /* isSpellChecker */);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static KeyboardLayoutSet createKeyboardSet(final Context context,
|
private static KeyboardLayoutSet createKeyboardSet(final Context context,
|
||||||
final InputMethodSubtype subtype, final int width, final int height,
|
final InputMethodSubtype subtype, final int width, final int height,
|
||||||
final boolean testCasesHaveTouchCoordinates) {
|
final boolean testCasesHaveTouchCoordinates, final boolean isSpellChecker) {
|
||||||
final EditorInfo editorInfo = new EditorInfo();
|
final EditorInfo editorInfo = new EditorInfo();
|
||||||
editorInfo.inputType = InputType.TYPE_CLASS_TEXT;
|
editorInfo.inputType = InputType.TYPE_CLASS_TEXT;
|
||||||
final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder(
|
final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder(
|
||||||
context, editorInfo);
|
context, editorInfo);
|
||||||
builder.setScreenGeometry(width, height);
|
builder.setScreenGeometry(width, height);
|
||||||
builder.setSubtype(subtype);
|
builder.setSubtype(subtype);
|
||||||
|
builder.setIsSpellChecker(isSpellChecker);
|
||||||
if (!testCasesHaveTouchCoordinates) {
|
if (!testCasesHaveTouchCoordinates) {
|
||||||
// For spell checker and tests
|
// For spell checker and tests
|
||||||
builder.disableTouchPositionCorrectionData();
|
builder.disableTouchPositionCorrectionData();
|
||||||
|
|
Loading…
Reference in New Issue