Skip to content
Browse files

Merge pull request #56 from menny/master

some UI improvements
  • Loading branch information...
2 parents 096da70 + 894e0fb commit ee7b5545bb282a3180efec797e01aa57f531b2cd @menny menny committed Sep 7, 2012
Showing with 6,675 additions and 6,389 deletions.
  1. +2 −2 AndroidManifest.xml
  2. BIN res/drawable-hdpi/sym_keyboard_space.9.png
  3. 0 res/{drawable-xlarge/sym_keyboard_space.png → drawable-hdpi/sym_keyboard_space_back.png}
  4. BIN res/drawable-xlarge/sym_keyboard_space.9.png
  5. 0 res/{drawable-hdpi/sym_keyboard_space.png → drawable-xlarge/sym_keyboard_space_back.png}
  6. +6 −0 res/drawable/lean_dark_candidates_background.xml
  7. +1 −1 res/drawable/lean_dark_keyboard_background.xml
  8. BIN res/drawable/sym_keyboard_space.9.png
  9. 0 res/drawable/{sym_keyboard_space.png → sym_keyboard_space_back.png}
  10. 0 res/layout/{changelog_layout_75.xml → changelog_layout_76.xml}
  11. +23 −0 res/layout/changelog_layout_77.xml
  12. +8 −0 res/layout/prefs_addon_keyboard_theme_selector.xml
  13. +2 −0 res/values-large-land/dimens.xml
  14. +2 −0 res/values-large/dimens.xml
  15. +2 −0 res/values-xlarge-land/dimens.xml
  16. +2 −0 res/values-xlarge/dimens.xml
  17. +1 −0 res/values/dimens.xml
  18. +1 −1 res/values/settings_defaults_dont_translate.xml
  19. +2 −0 res/values/settings_keys_dont_translate.xml
  20. +4 −0 res/values/strings.xml
  21. +11 −5 res/values/styles.xml
  22. +3,590 −3,574 src/com/anysoftkeyboard/AnySoftKeyboard.java
  23. +2 −0 src/com/anysoftkeyboard/Configuration.java
  24. +8 −0 src/com/anysoftkeyboard/ConfigurationImpl.java
  25. +278 −241 src/com/anysoftkeyboard/dictionaries/ResourceBinaryDictionary.java
  26. +4 −1 src/com/anysoftkeyboard/keyboards/AnyKeyboard.java
  27. +2,697 −2,555 src/com/anysoftkeyboard/keyboards/views/AnyKeyboardBaseView.java
  28. +29 −9 src/com/anysoftkeyboard/utils/IMEUtil.java
View
4 AndroidManifest.xml
@@ -1,7 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.menny.android.anysoftkeyboard"
- android:versionCode="75"
- android:versionName="20120814-eye-candy" >
+ android:versionCode="77"
+ android:versionName="20120905-eye-candy" >
<supports-screens
android:anyDensity="true"
View
BIN res/drawable-hdpi/sym_keyboard_space.9.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
0 res/drawable-xlarge/sym_keyboard_space.png → ...drawable-hdpi/sym_keyboard_space_back.png
File renamed without changes
View
BIN res/drawable-xlarge/sym_keyboard_space.9.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
0 res/drawable-hdpi/sym_keyboard_space.png → ...awable-xlarge/sym_keyboard_space_back.png
File renamed without changes
View
6 res/drawable/lean_dark_candidates_background.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="#FF161616" />
+</shape>
View
2 res/drawable/lean_dark_keyboard_background.xml
@@ -5,6 +5,6 @@
<gradient
android:angle="90"
android:endColor="#FF161616"
- android:startColor="#FF060606"
+ android:startColor="#F000"
android:type="linear" />
</shape>
View
BIN res/drawable/sym_keyboard_space.9.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
0 res/drawable/sym_keyboard_space.png → res/drawable/sym_keyboard_space_back.png
File renamed without changes
View
0 res/layout/changelog_layout_75.xml → res/layout/changelog_layout_76.xml
File renamed without changes.
View
23 res/layout/changelog_layout_77.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 AnySoftKeyboard
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:tag="20120904-eye-candy"
+ android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content">
+ <TextView android:layout_height="wrap_content" android:layout_width="fill_parent"
+ android:text="* Some UI improvement.\n* New translations: .\n* Bug fixes." style="@android:style/TextAppearance.Small"/>
+
+</LinearLayout>
View
8 res/layout/prefs_addon_keyboard_theme_selector.xml
@@ -93,6 +93,14 @@
android:summary="@string/custom_hint_valign_summary"
android:title="@string/custom_hint_valign" />
+ <CheckBoxPreference
+ android:defaultValue="@bool/settings_default_show_keyboard_name_text_value"
+ android:key="@string/settings_key_show_keyboard_name_text_key"
+ android:persistent="true"
+ android:summaryOff="@string/show_keyboard_name_off_summary"
+ android:summaryOn="@string/show_keyboard_name_on_summary"
+ android:title="@string/show_keyboard_name_text" />
+
<EditTextPreference
android:autoText="false"
android:capitalize="none"
View
2 res/values-large-land/dimens.xml
@@ -32,6 +32,8 @@
<dimen name="lean_key_text_size">21sp</dimen>
<dimen name="key_label_text_size">16sp</dimen>
+ <dimen name="keyboard_name_text_size">11sp</dimen>
+
<dimen name="candidate_strip_height">40dip</dimen>
<dimen name="candidate_font_height">23sp</dimen>
View
2 res/values-large/dimens.xml
@@ -35,6 +35,8 @@
<dimen name="key_label_text_size">17sp</dimen>
<dimen name="key_hint_text_size">8sp</dimen>
+ <dimen name="keyboard_name_text_size">12sp</dimen>
+
<dimen name="candidate_strip_height">44sp</dimen>
<dimen name="candidate_font_height">24sp</dimen>
View
2 res/values-xlarge-land/dimens.xml
@@ -32,6 +32,8 @@
<dimen name="lean_key_text_size">24sp</dimen>
<dimen name="key_label_text_size">19sp</dimen>
+ <dimen name="keyboard_name_text_size">14sp</dimen>
+
<dimen name="candidate_strip_height">40dip</dimen>
<dimen name="candidate_font_height">24sp</dimen>
View
2 res/values-xlarge/dimens.xml
@@ -34,6 +34,8 @@
<dimen name="key_label_text_size">20sp</dimen>
<dimen name="key_hint_text_size">10sp</dimen>
+ <dimen name="keyboard_name_text_size">15sp</dimen>
+
<dimen name="candidate_strip_height">42dip</dimen>
<dimen name="candidate_font_height">25sp</dimen>
View
1 res/values/dimens.xml
@@ -38,6 +38,7 @@
<dimen name="key_label_text_size">14sp</dimen>
<dimen name="key_hint_text_size">7sp</dimen>
<dimen name="key_hint_text_no_size">0px</dimen>
+ <dimen name="keyboard_name_text_size">10sp</dimen>
<dimen name="candidate_strip_height">36dp</dimen>
<dimen name="candidate_font_height">18sp</dimen>
View
2 res/values/settings_defaults_dont_translate.xml
@@ -25,7 +25,7 @@
<bool name="settings_default_key_press_shows_preview_popup">true</bool>
<bool name="settings_default_use_custom_keytext_color_value">false</bool>
-
+ <bool name="settings_default_show_keyboard_name_text_value">true</bool>
<bool name="settings_default_show_hint_text_value">true</bool>
<bool name="settings_default_use_custom_hint_color_value">false</bool>
<bool name="settings_default_use_custom_hint_align_value">false</bool>
View
2 res/values/settings_keys_dont_translate.xml
@@ -16,6 +16,8 @@
<string name="settings_key_use_custom_keytext_color_key">settings_key_use_custom_keytext_color_key</string>
+ <string name="settings_key_show_keyboard_name_text_key">settings_key_show_keyboard_name_text_key</string>
+
<string name="settings_key_show_hint_text_key">settings_key_show_hint_text_key</string>
<string name="settings_key_use_custom_hint_color_key">settings_key_use_custom_hint_color_key</string>
<string name="settings_key_use_custom_hint_align_key">settings_key_use_custom_hint_align</string>
View
4 res/values/strings.xml
@@ -278,6 +278,10 @@
<string name="tweak_dictionary_group">Dictionary tweaks</string>
<string name="settings_min_length_for_word_correction">Minimum word length for correction</string>
+ <string name="show_keyboard_name_text">Show keyboard name</string>
+ <string name="show_keyboard_name_on_summary">Show keyboard name on space-bar</string>
+ <string name="show_keyboard_name_off_summary">Never show keyboard name</string>
+
<string name="use_custom_keytext_color">Override key text color</string>
<string name="use_custom_keytext_color_on_summary">Use custom key text color</string>
<string name="use_custom_keytext_color_off_summary">Use theme key text color</string>
View
16 res/values/styles.xml
@@ -19,7 +19,7 @@
<item name="keyPreviewOffset">@dimen/key_preview_offset</item>
<item name="keyPreviewHeight">@dimen/key_preview_height</item>
-->
-<resources>
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="Popup" parent="@android:style/Theme.Dialog">
<item name="android:windowContentOverlay">@null</item>
<item name="android:maxWidth">320dp</item>
@@ -67,7 +67,10 @@
<item name="keyTextSize">@dimen/key_text_size</item>
<item name="keyTextStyle">bold</item>
<item name="keyTextColor">#FFFFFFFF</item>
- <item name="labelTextSize">@dimen/key_label_text_size</item>
+ <item name="labelTextSize">@dimen/key_label_text_size</item>
+
+ <item name="keyboardNameTextSize">@dimen/keyboard_name_text_size</item>
+ <item name="keyboardNameTextColor">#FAAA</item>
<item name="keyHysteresisDistance">@dimen/key_hysteresis_distance</item>
<!-- this is what Android team figured verticalCorrection should be -->
@@ -133,9 +136,12 @@
<item name="keyVerticalGap">@dimen/plain_theme_key_horizontal_gap</item>
<item name="keyBackground">@drawable/lean_dark_btn</item>
<item name="keyPreviewBackground">@drawable/lean_dark_popup_keyboard_background</item>
-<!--
- <item name="keyTextSize">@dimen/lean_key_text_size</item>
--->
+ <item name="suggestionBackgroundImage">@drawable/lean_dark_candidates_background</item>
+
+ <!-- I said Lean theme, so no garbage on the screen please. -->
+ <item name="keyboardNameTextColor">#F666</item>
+ <item name="hintTextSize">0px</item>
+
<item name="keyTextStyle">normal</item>
<item name="shadowRadius">0px</item>
</style>
View
7,164 src/com/anysoftkeyboard/AnySoftKeyboard.java
3,590 additions, 3,574 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
2 src/com/anysoftkeyboard/Configuration.java
@@ -15,6 +15,8 @@
//String getChangeLayoutKeysSize();
boolean getShowKeyPreview();
+
+ boolean getShowKeyboardNameText();
boolean getShowHintTextOnKeys();
View
8 src/com/anysoftkeyboard/ConfigurationImpl.java
@@ -34,6 +34,7 @@
private boolean mKeyPreviewAboveKey = true;
private boolean mSwapPunctuationAndSpace = true;
private boolean mShowHintTextOnKeys = true;
+ private boolean mShowKeyboardNameText = true;
private boolean mUseCustomHintAlign = true;
private int mCustomHintAlign = Gravity.BOTTOM;
private int mCustomHintVAlign = Gravity.TOP;
@@ -247,6 +248,9 @@ public void onSharedPreferenceChanged(SharedPreferences sp, String key) {
mContext.getString(R.string.settings_default_key_press_preview_popup_position)).equals("above_key");
Log.i(TAG, "** mKeyPreviewAboveKey: "+mKeyPreviewAboveKey);
+ mShowKeyboardNameText = sp.getBoolean(mContext.getString(R.string.settings_key_show_keyboard_name_text_key),
+ mContext.getResources().getBoolean(R.bool.settings_default_show_keyboard_name_text_value));
+ Log.i(TAG, "** mShowKeyboardNameText: "+mShowKeyboardNameText);
mShowHintTextOnKeys = sp.getBoolean(mContext.getString(R.string.settings_key_show_hint_text_key),
mContext.getResources().getBoolean(R.bool.settings_default_show_hint_text_value));
@@ -718,6 +722,10 @@ public int getCustomHintVAlign() {
return mCustomHintVAlign;
}
+ public boolean getShowKeyboardNameText() {
+ return mShowKeyboardNameText;
+ }
+
public boolean useChewbaccaNotifications() {
return mUseChewbacca;
}
View
519 src/com/anysoftkeyboard/dictionaries/ResourceBinaryDictionary.java
@@ -17,263 +17,300 @@
package com.anysoftkeyboard.dictionaries;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.Channels;
import java.util.Arrays;
-import com.anysoftkeyboard.WordComposer;
-import com.anysoftkeyboard.utils.IMEUtil;
-
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.AsyncTask;
import android.util.Log;
+import com.anysoftkeyboard.WordComposer;
+import com.anysoftkeyboard.utils.IMEUtil.GCUtils;
+import com.anysoftkeyboard.utils.IMEUtil.GCUtils.MemRelatedOperation;
+
/**
* Implements a static, compacted, binary dictionary of standard words.
*/
public class ResourceBinaryDictionary extends Dictionary {
- /**
- * There is difference between what java and native code can handle.
- * This value should only be used in BinaryDictionary.java
- * It is necessary to keep it at this value because some languages e.g. German have
- * really long words.
- */
- protected static final int MAX_WORD_LENGTH = 48;
-
- private static final String TAG = "ASK_ResBinDict";
- private static final int MAX_ALTERNATIVES = 16;
- private static final int MAX_WORDS = 18;
- private static final int MAX_BIGRAMS = 60;
-
- private static final boolean ENABLE_MISSED_CHARACTERS = true;
-
- //private int mDicTypeId;
- private int mNativeDict;
- private int mDictLength;
- private int[] mInputCodes = new int[MAX_WORD_LENGTH * MAX_ALTERNATIVES];
- private char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS];
- private char[] mOutputChars_bigrams = new char[MAX_WORD_LENGTH * MAX_BIGRAMS];
- private int[] mFrequencies = new int[MAX_WORDS];
- private final Context mAppContext;
- private final int mDictResId;
- //private int[] mFrequencies_bigrams = new int[MAX_BIGRAMS];
- // Keep a reference to the native dict direct buffer in Java to avoid
- // unexpected deallocation of the direct buffer.
- private ByteBuffer mNativeDictDirectBuffer;
-
- static {
- try {
- System.loadLibrary("anysoftkey2_jni");
- }
- catch (UnsatisfiedLinkError ule) {
- Log.e(TAG, "******** Could not load native library nativeim ********");
- Log.e(TAG, "******** Could not load native library nativeim ********", ule);
- Log.e(TAG, "******** Could not load native library nativeim ********");
- }
- catch (Throwable t) {
- Log.e(TAG, "******** Failed to load native dictionary library ********");
- Log.e(TAG, "******** Failed to load native dictionary library *******", t);
- Log.e(TAG, "******** Failed to load native dictionary library ********");
- }
- }
-
- /**
- * Create a dictionary from a raw resource file
- * @param context application context for reading resources
- * @param resId the resource containing the raw binary dictionary
- */
- public ResourceBinaryDictionary(String dictionaryName, Context context, int resId/*, int dicTypeId*/) {
- super(dictionaryName);
- mAppContext = context;
- mDictResId = resId;
- }
-
- private native int openNative(ByteBuffer bb, int typedLetterMultiplier, int fullWordMultiplier);
- private native void closeNative(int dict);
- private native boolean isValidWordNative(int nativeData, char[] word, int wordLength);
- private native int getSuggestionsNative(int dict, int[] inputCodes, int codesSize,
- char[] outputChars, int[] frequencies, int maxWordLength, int maxWords,
- int maxAlternatives, int skipPos, int[] nextLettersFrequencies, int nextLettersSize);
- /*private native int getBigramsNative(int dict, char[] prevWord, int prevWordLength,
- int[] inputCodes, int inputCodesLength, char[] outputChars, int[] frequencies,
- int maxWordLength, int maxBigrams, int maxAlternatives);*/
-
- @Override
- public void loadDictionary()
- {
- new LoadDictionaryTask().execute();
- }
-
- private class LoadDictionaryTask extends AsyncTask<Void, Void, Void> {
- @Override
- protected Void doInBackground(Void... v) {
- IMEUtil.GCUtils.getInstance().reset();
- boolean tryGC = true;
-
- Resources pkgRes = mAppContext.getResources();
- int[] resId;
- //is it an array of dictionaries? Or a ref to raw?
- final String dictResType = pkgRes.getResourceTypeName(mDictResId);
- if (dictResType.equalsIgnoreCase("raw"))
- {
- resId = new int[]{mDictResId};
- }
- else
- {
- Log.d(TAG, "type "+dictResType);
- TypedArray a = pkgRes.obtainTypedArray(mDictResId);
- resId = new int[a.length()];
- for(int index=0; index<a.length(); index++)
- resId[index] = a.getResourceId(index, 0);
- }
-
- for (int i = 0; i < IMEUtil.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
- try {
- //The try-catch is for issue 878: http://code.google.com/p/softkeyboard/issues/detail?id=878
- try
- {
- mNativeDict = 0;
- loadDictionary(mAppContext, resId);
- }
- catch(UnsatisfiedLinkError ex)
- {
- Log.w(TAG, "Failed to load binary JNI connection! Error: "+ex.getMessage());
- }
-
- tryGC = false;
- } catch (OutOfMemoryError e) {
- tryGC = IMEUtil.GCUtils.getInstance().tryGCOrWait(TAG, e);
- }
- }
+ /**
+ * There is difference between what java and native code can handle. This
+ * value should only be used in BinaryDictionary.java It is necessary to
+ * keep it at this value because some languages e.g. German have really long
+ * words.
+ */
+ protected static final int MAX_WORD_LENGTH = 48;
+
+ private static final String TAG = "ASK_ResBinDict";
+ private static final int MAX_ALTERNATIVES = 16;
+ private static final int MAX_WORDS = 18;
+ private static final int MAX_BIGRAMS = 60;
+
+ private static final boolean ENABLE_MISSED_CHARACTERS = true;
+
+ // private int mDicTypeId;
+ private int mNativeDict;
+ private int mDictLength;
+ private int[] mInputCodes = new int[MAX_WORD_LENGTH * MAX_ALTERNATIVES];
+ private char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS];
+ private char[] mOutputChars_bigrams = new char[MAX_WORD_LENGTH
+ * MAX_BIGRAMS];
+ private int[] mFrequencies = new int[MAX_WORDS];
+ private final Context mAppContext;
+ private final int mDictResId;
+ // private int[] mFrequencies_bigrams = new int[MAX_BIGRAMS];
+ // Keep a reference to the native dict direct buffer in Java to avoid
+ // unexpected deallocation of the direct buffer.
+ private ByteBuffer mNativeDictDirectBuffer;
+
+ static {
+ try {
+ System.loadLibrary("anysoftkey2_jni");
+ } catch (UnsatisfiedLinkError ule) {
+ Log.e(TAG,
+ "******** Could not load native library nativeim ********");
+ Log.e(TAG,
+ "******** Could not load native library nativeim ********",
+ ule);
+ Log.e(TAG,
+ "******** Could not load native library nativeim ********");
+ } catch (Throwable t) {
+ Log.e(TAG,
+ "******** Failed to load native dictionary library ********");
+ Log.e(TAG,
+ "******** Failed to load native dictionary library *******",
+ t);
+ Log.e(TAG,
+ "******** Failed to load native dictionary library ********");
+ }
+ }
+
+ /**
+ * Create a dictionary from a raw resource file
+ *
+ * @param context
+ * application context for reading resources
+ * @param resId
+ * the resource containing the raw binary dictionary
+ */
+ public ResourceBinaryDictionary(String dictionaryName, Context context,
+ int resId/* , int dicTypeId */) {
+ super(dictionaryName);
+ mAppContext = context;
+ mDictResId = resId;
+ }
+
+ private native int openNative(ByteBuffer bb, int typedLetterMultiplier,
+ int fullWordMultiplier);
+
+ private native void closeNative(int dict);
+
+ private native boolean isValidWordNative(int nativeData, char[] word,
+ int wordLength);
+
+ private native int getSuggestionsNative(int dict, int[] inputCodes,
+ int codesSize, char[] outputChars, int[] frequencies,
+ int maxWordLength, int maxWords, int maxAlternatives, int skipPos,
+ int[] nextLettersFrequencies, int nextLettersSize);
+
+ /*
+ * private native int getBigramsNative(int dict, char[] prevWord, int
+ * prevWordLength, int[] inputCodes, int inputCodesLength, char[]
+ * outputChars, int[] frequencies, int maxWordLength, int maxBigrams, int
+ * maxAlternatives);
+ */
+
+ @Override
+ public void loadDictionary() {
+ new LoadDictionaryTask().execute();
+ }
+
+ private class LoadDictionaryTask extends AsyncTask<Void, Void, Void> {
+ @Override
+ protected Void doInBackground(Void... v) {
+
+ Resources pkgRes = mAppContext.getResources();
+ final int[] resId;
+ // is it an array of dictionaries? Or a ref to raw?
+ final String dictResType = pkgRes.getResourceTypeName(mDictResId);
+ if (dictResType.equalsIgnoreCase("raw")) {
+ resId = new int[] { mDictResId };
+ } else {
+ Log.d(TAG, "type " + dictResType);
+ TypedArray a = pkgRes.obtainTypedArray(mDictResId);
+ resId = new int[a.length()];
+ for (int index = 0; index < a.length(); index++)
+ resId[index] = a.getResourceId(index, 0);
+ }
+
+ GCUtils.getInstance().peformOperationWithMemRetry(TAG,
+ new MemRelatedOperation() {
+
+ public void operation() {
+ // The try-catch is for issue 878:
+ // http://code.google.com/p/softkeyboard/issues/detail?id=878
+ try {
+ mNativeDict = 0;
+ loadDictionary(mAppContext, resId);
+ } catch (UnsatisfiedLinkError ex) {
+ Log.w(TAG,
+ "Failed to load binary JNI connection! Error: "
+ + ex.getMessage());
+ }
+ }
+ }, false);
return null;
- }
- }
-
- private final void loadDictionary(Context context, int[] resId) {
- InputStream[] is = null;
- try {
- // merging separated dictionary into one if dictionary is separated
- int total = 0;
- is = new InputStream[resId.length];
- for (int i = 0; i < resId.length; i++) {
- //http://ponystyle.com/blog/2010/03/26/dealing-with-asset-compression-in-android-apps/
- //NOTE: the resource file can not be larger than 1MB
- is[i] = context.getResources().openRawResource(resId[i]);
- final int dictSize = is[i].available();
- Log.d(TAG, "Will load a resource dictionary id "+resId[i]+" whose size is "+dictSize+" bytes.");
- total += dictSize;
- }
-
- mNativeDictDirectBuffer =
- ByteBuffer.allocateDirect(total).order(ByteOrder.nativeOrder());
- int got = 0;
- for (int i = 0; i < resId.length; i++) {
- got += Channels.newChannel(is[i]).read(mNativeDictDirectBuffer);
- }
- if (got != total) {
- Log.e(TAG, "Read " + got + " bytes, expected " + total);
- } else {
- mNativeDict = openNative(mNativeDictDirectBuffer,
- TYPED_LETTER_MULTIPLIER, FULL_WORD_FREQ_MULTIPLIER);
- mDictLength = total;
- }
- } catch (IOException e) {
- Log.w(TAG, "No available memory for binary dictionary: "+e.getMessage());
- } finally {
- try {
- if (is != null) {
- for (int i = 0; i < is.length; i++) {
- is[i].close();
- }
- }
- } catch (IOException e) {
- Log.w(TAG, "Failed to close input stream");
- }
- }
- }
-
- @Override
- public void getWords(final WordComposer codes, final WordCallback callback/*,
- int[] nextLettersFrequencies*/) {
- if (mNativeDict == 0) return;
- final int codesSize = codes.size();
- // Won't deal with really long words.
- if (codesSize > MAX_WORD_LENGTH - 1) return;
-
- Arrays.fill(mInputCodes, -1);
- for (int i = 0; i < codesSize; i++) {
- int[] alternatives = codes.getCodesAt(i);
- System.arraycopy(alternatives, 0, mInputCodes, i * MAX_ALTERNATIVES,
- Math.min(alternatives.length, MAX_ALTERNATIVES));
- }
- Arrays.fill(mOutputChars, (char) 0);
- Arrays.fill(mFrequencies, 0);
-
- int[] nextLettersFrequencies = null;
-
- int count = getSuggestionsNative(mNativeDict, mInputCodes, codesSize,
- mOutputChars, mFrequencies,
- MAX_WORD_LENGTH, MAX_WORDS, MAX_ALTERNATIVES, -1,
- nextLettersFrequencies,
- nextLettersFrequencies != null ? nextLettersFrequencies.length : 0);
-
- // If there aren't sufficient suggestions, search for words by allowing wild cards at
- // the different character positions. This feature is not ready for prime-time as we need
- // to figure out the best ranking for such words compared to proximity corrections and
- // completions.
- if (ENABLE_MISSED_CHARACTERS && count < 5) {
- for (int skip = 0; skip < codesSize; skip++) {
- int tempCount = getSuggestionsNative(mNativeDict, mInputCodes, codesSize,
- mOutputChars, mFrequencies,
- MAX_WORD_LENGTH, MAX_WORDS, MAX_ALTERNATIVES, skip,
- null, 0);
- count = Math.max(count, tempCount);
- if (tempCount > 0) break;
- }
- }
-
- for (int j = 0; j < count; j++) {
- if (mFrequencies[j] < 1) break;
- int start = j * MAX_WORD_LENGTH;
- int len = 0;
- while (mOutputChars[start + len] != 0) {
- len++;
- }
- if (len > 0) {
- callback.addWord(mOutputChars, start, len, mFrequencies[j]/*, mDicTypeId,
- DataType.UNIGRAM*/);
- }
- }
- }
-
- @Override
- public boolean isValidWord(CharSequence word) {
- if (word == null || mNativeDict == 0) return false;
- char[] chars = word.toString().toCharArray();
- return isValidWordNative(mNativeDict, chars, chars.length);
- }
-
- public int getSize() {
- return mDictLength; // This value is initialized on the call to openNative()
- }
-
- @Override
- public synchronized void close() {
- if (mNativeDict != 0) {
- closeNative(mNativeDict);
- mNativeDict = 0;
- }
- }
-
- @Override
- protected void finalize() throws Throwable {
- close();
- super.finalize();
- }
+ }
+ }
+
+ private final void loadDictionary(Context context, int[] resId) {
+ InputStream[] is = null;
+ try {
+ // merging separated dictionary into one if dictionary is separated
+ int total = 0;
+ is = new InputStream[resId.length];
+ for (int i = 0; i < resId.length; i++) {
+ // http://ponystyle.com/blog/2010/03/26/dealing-with-asset-compression-in-android-apps/
+ // NOTE: the resource file can not be larger than 1MB
+ is[i] = context.getResources().openRawResource(resId[i]);
+ final int dictSize = is[i].available();
+ Log.d(TAG, "Will load a resource dictionary id " + resId[i]
+ + " whose size is " + dictSize + " bytes.");
+ total += dictSize;
+ }
+
+ mNativeDictDirectBuffer = ByteBuffer.allocateDirect(total).order(
+ ByteOrder.nativeOrder());
+ int got = 0;
+ for (int i = 0; i < resId.length; i++) {
+ got += Channels.newChannel(is[i]).read(mNativeDictDirectBuffer);
+ }
+ if (got != total) {
+ Log.e(TAG, "Read " + got + " bytes, expected " + total);
+ } else {
+ mNativeDict = openNative(mNativeDictDirectBuffer,
+ TYPED_LETTER_MULTIPLIER, FULL_WORD_FREQ_MULTIPLIER);
+ mDictLength = total;
+ }
+ } catch (IOException e) {
+ Log.w(TAG,
+ "No available memory for binary dictionary: "
+ + e.getMessage());
+ } finally {
+ try {
+ if (is != null) {
+ for (int i = 0; i < is.length; i++) {
+ is[i].close();
+ }
+ }
+ } catch (IOException e) {
+ Log.w(TAG, "Failed to close input stream");
+ }
+ }
+ }
+
+ @Override
+ public void getWords(final WordComposer codes, final WordCallback callback/*
+ * ,
+ * int
+ * [
+ * ]
+ * nextLettersFrequencies
+ */) {
+ if (mNativeDict == 0)
+ return;
+ final int codesSize = codes.size();
+ // Won't deal with really long words.
+ if (codesSize > MAX_WORD_LENGTH - 1)
+ return;
+
+ Arrays.fill(mInputCodes, -1);
+ for (int i = 0; i < codesSize; i++) {
+ int[] alternatives = codes.getCodesAt(i);
+ System.arraycopy(alternatives, 0, mInputCodes,
+ i * MAX_ALTERNATIVES,
+ Math.min(alternatives.length, MAX_ALTERNATIVES));
+ }
+ Arrays.fill(mOutputChars, (char) 0);
+ Arrays.fill(mFrequencies, 0);
+
+ int[] nextLettersFrequencies = null;
+
+ int count = getSuggestionsNative(mNativeDict, mInputCodes, codesSize,
+ mOutputChars, mFrequencies, MAX_WORD_LENGTH, MAX_WORDS,
+ MAX_ALTERNATIVES, -1, nextLettersFrequencies,
+ nextLettersFrequencies != null ? nextLettersFrequencies.length
+ : 0);
+
+ // If there aren't sufficient suggestions, search for words by allowing
+ // wild cards at
+ // the different character positions. This feature is not ready for
+ // prime-time as we need
+ // to figure out the best ranking for such words compared to proximity
+ // corrections and
+ // completions.
+ if (ENABLE_MISSED_CHARACTERS && count < 5) {
+ for (int skip = 0; skip < codesSize; skip++) {
+ int tempCount = getSuggestionsNative(mNativeDict, mInputCodes,
+ codesSize, mOutputChars, mFrequencies, MAX_WORD_LENGTH,
+ MAX_WORDS, MAX_ALTERNATIVES, skip, null, 0);
+ count = Math.max(count, tempCount);
+ if (tempCount > 0)
+ break;
+ }
+ }
+
+ for (int j = 0; j < count; j++) {
+ if (mFrequencies[j] < 1)
+ break;
+ int start = j * MAX_WORD_LENGTH;
+ int len = 0;
+ while (mOutputChars[start + len] != 0) {
+ len++;
+ }
+ if (len > 0) {
+ callback.addWord(mOutputChars, start, len, mFrequencies[j]/*
+ * ,
+ * mDicTypeId
+ * ,
+ * DataType
+ * .
+ * UNIGRAM
+ */);
+ }
+ }
+ }
+
+ @Override
+ public boolean isValidWord(CharSequence word) {
+ if (word == null || mNativeDict == 0)
+ return false;
+ char[] chars = word.toString().toCharArray();
+ return isValidWordNative(mNativeDict, chars, chars.length);
+ }
+
+ public int getSize() {
+ return mDictLength; // This value is initialized on the call to
+ // openNative()
+ }
+
+ @Override
+ public synchronized void close() {
+ if (mNativeDict != 0) {
+ closeNative(mNativeDict);
+ mNativeDict = 0;
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ close();
+ super.finalize();
+ }
}
View
5 src/com/anysoftkeyboard/keyboards/AnyKeyboard.java
@@ -599,7 +599,10 @@ public void setImeOptions(Resources res, EditorInfo editor) {
public String getKeyboardName()
{
- return mKeyboardContext.getResources().getString(getKeyboardNameResId());
+ final int nameId= getKeyboardNameResId();
+ if (nameId == -1)
+ return null;
+ return mKeyboardContext.getResources().getString(nameId);
}
public boolean isLeftToRightLanguage()
View
5,252 src/com/anysoftkeyboard/keyboards/views/AnyKeyboardBaseView.java
2,697 additions, 2,555 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
38 src/com/anysoftkeyboard/utils/IMEUtil.java
@@ -41,36 +41,56 @@ public static void cancelTask(AsyncTask<?, ?, ?> task, boolean mayInterruptIfRun
}
public static class GCUtils {
- private static final String TAG = "GCUtils";
- public static final int GC_TRY_COUNT = 2;
+ public static interface MemRelatedOperation {
+ void operation();
+ }
+ private static final int GC_TRY_COUNT = 2;
// GC_TRY_LOOP_MAX is used for the hard limit of GC wait,
// GC_TRY_LOOP_MAX should be greater than GC_TRY_COUNT.
- public static final int GC_TRY_LOOP_MAX = 5;
+ private static final int GC_TRY_LOOP_MAX = 5;
private static final long GC_INTERVAL = DateUtils.SECOND_IN_MILLIS;
private static GCUtils sInstance = new GCUtils();
private int mGCTryCount = 0;
public static GCUtils getInstance() {
return sInstance;
}
+
+ public boolean peformOperationWithMemRetry(String TAG, MemRelatedOperation operation, boolean failWithException) {
+ reset();
+
+ boolean retry = true;
+ try {
+ while(retry) {
+ operation.operation();
+ return true;
+ }
+ } catch (OutOfMemoryError e) {
+ Log.w(TAG,
+ "WOW! No memory for operation... I'll try to release some.");
+ retry = tryGCOrWait(TAG, e);
+ if (!retry && failWithException) throw e;
+ }
+ return false;
+ }
- public void reset() {
+ private void reset() {
mGCTryCount = 0;
}
- public boolean tryGCOrWait(String metaData, Throwable t) {
- if (mGCTryCount == 0) {
+ private boolean tryGCOrWait(String metaData, Throwable t) {
+ if (mGCTryCount % GC_TRY_COUNT == 0) {
System.gc();
}
- if (++mGCTryCount > GC_TRY_COUNT) {
- //ImeLogger.logOnException(metaData, t);
+ if (mGCTryCount > GC_TRY_LOOP_MAX) {
return false;
} else {
+ mGCTryCount++;
try {
Thread.sleep(GC_INTERVAL);
return true;
} catch (InterruptedException e) {
- Log.e(TAG, "Sleep was interrupted.");
+ Log.e(metaData, "Sleep was interrupted.");
//ImeLogger.logOnException(metaData, t);
return false;
}

0 comments on commit ee7b554

Please sign in to comment.
Something went wrong with that request. Please try again.