aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--base/build.gradle22
-rw-r--r--base/src/main/java/com/anysoftkeyboard/base/utils/GCUtils.java62
-rw-r--r--jnidictionaryv1/build.gradle16
-rw-r--r--jnidictionaryv1/src/main/java/com/anysoftkeyboard/dictionaries/jni/BinaryDictionary.java (renamed from src/main/java/com/anysoftkeyboard/dictionaries/jni/BinaryDictionary.java)4
-rw-r--r--jnidictionaryv2/build.gradle16
-rw-r--r--jnidictionaryv2/src/main/java/com/anysoftkeyboard/dictionaries/jni/ResourceBinaryDictionary.java (renamed from src/main/java/com/anysoftkeyboard/dictionaries/jni/ResourceBinaryDictionary.java)9
-rw-r--r--src/main/java/com/anysoftkeyboard/AnySoftKeyboard.java4
-rw-r--r--src/main/java/com/anysoftkeyboard/keyboards/views/AnyKeyboardBaseView.java4
-rw-r--r--src/main/java/com/anysoftkeyboard/utils/EditingUtil.java336
-rw-r--r--src/main/java/com/anysoftkeyboard/utils/IMEUtil.java58
10 files changed, 88 insertions, 443 deletions
diff --git a/base/build.gradle b/base/build.gradle
index e11e5f5cc..d160358bf 100644
--- a/base/build.gradle
+++ b/base/build.gradle
@@ -1,21 +1,4 @@
-buildscript {
- repositories {
- mavenLocal()
- mavenCentral()
- maven {
- url 'https://oss.sonatype.org/content/repositories/snapshots/'
- }
- }
- dependencies {
- classpath 'com.android.tools.build:gradle:1.2.3'
- classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.0'
- }
-}
-
-apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.library'
-apply plugin: 'pmd'
-apply plugin: 'jacoco'
android {
compileSdkVersion 22
@@ -27,11 +10,6 @@ android {
versionCode 1
versionName "1.0"
}
- buildTypes {
- release {
- minifyEnabled false
- }
- }
}
dependencies {
diff --git a/base/src/main/java/com/anysoftkeyboard/base/utils/GCUtils.java b/base/src/main/java/com/anysoftkeyboard/base/utils/GCUtils.java
new file mode 100644
index 000000000..d22c72d4c
--- /dev/null
+++ b/base/src/main/java/com/anysoftkeyboard/base/utils/GCUtils.java
@@ -0,0 +1,62 @@
+package com.anysoftkeyboard.base.utils;
+
+import android.text.format.DateUtils;
+import android.util.Log;
+
+public class GCUtils {
+ 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.
+ private static final int GC_TRY_LOOP_MAX = 5;
+ private static final long GC_INTERVAL = DateUtils.SECOND_IN_MILLIS;
+ private static final GCUtils sInstance = new GCUtils();
+ private int mGCTryCount = 0;
+
+ public static GCUtils getInstance() {
+ return sInstance;
+ }
+
+ public boolean performOperationWithMemRetry(String TAG, MemRelatedOperation operation, boolean failWithException) {
+ reset();
+
+ boolean retry = true;
+ while (retry) {
+ try {
+ 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;
+ }
+
+ private void reset() {
+ mGCTryCount = 0;
+ }
+
+ private boolean tryGCOrWait(String metaData, Throwable t) {
+ if (mGCTryCount % GC_TRY_COUNT == 0) {
+ System.gc();
+ }
+ if (mGCTryCount > GC_TRY_LOOP_MAX) {
+ return false;
+ } else {
+ mGCTryCount++;
+ try {
+ Thread.sleep(GC_INTERVAL);
+ return true;
+ } catch (InterruptedException e) {
+ Log.e(metaData, "Sleep was interrupted.");
+ //ImeLogger.logOnException(metaData, t);
+ return false;
+ }
+ }
+ }
+
+ public interface MemRelatedOperation {
+ void operation();
+ }
+}
diff --git a/jnidictionaryv1/build.gradle b/jnidictionaryv1/build.gradle
index 0c54c90df..8fb981e4e 100644
--- a/jnidictionaryv1/build.gradle
+++ b/jnidictionaryv1/build.gradle
@@ -1,24 +1,24 @@
apply plugin: 'com.android.library'
android {
- compileSdkVersion 21
- buildToolsVersion "21.1.2"
+ compileSdkVersion 22
+ buildToolsVersion "22.0.1"
defaultConfig {
minSdkVersion 7
- targetSdkVersion 21
+ targetSdkVersion 22
versionCode 1
versionName "1.0"
ndk {
moduleName "anysoftkey_jni"
}
}
- buildTypes {
- release {
- minifyEnabled false
- }
- }
}
dependencies {
+ repositories {
+ mavenCentral()
+ }
+ compile 'net.evendanan.anysoftkeyboard:api:1.2.3'
+ compile project(':base')
}
diff --git a/src/main/java/com/anysoftkeyboard/dictionaries/jni/BinaryDictionary.java b/jnidictionaryv1/src/main/java/com/anysoftkeyboard/dictionaries/jni/BinaryDictionary.java
index 85b0d2a74..adb9194fd 100644
--- a/src/main/java/com/anysoftkeyboard/dictionaries/jni/BinaryDictionary.java
+++ b/jnidictionaryv1/src/main/java/com/anysoftkeyboard/dictionaries/jni/BinaryDictionary.java
@@ -17,10 +17,10 @@
package com.anysoftkeyboard.dictionaries.jni;
import android.content.res.AssetFileDescriptor;
+import android.util.Log;
import com.anysoftkeyboard.base.dictionaries.Dictionary;
import com.anysoftkeyboard.base.dictionaries.WordComposer;
-import com.anysoftkeyboard.utils.Log;
import java.io.FileDescriptor;
import java.util.Arrays;
@@ -65,7 +65,7 @@ public class BinaryDictionary extends Dictionary {
try {
mNativeDict = 0;
long startTime = System.currentTimeMillis();
- mNativeDict = openNative(mAfd.getFileDescriptor(), mAfd.getStartOffset(), mAfd.getLength(), TYPED_LETTER_MULTIPLIER, FULL_WORD_FREQ_MULTIPLIER);
+ mNativeDict = openNative(mAfd.getFileDescriptor(), mAfd.getStartOffset(), mAfd.getLength(), Dictionary.TYPED_LETTER_MULTIPLIER, Dictionary.FULL_WORD_FREQ_MULTIPLIER);
Log.d(TAG, "Loaded dictionary in " + (System.currentTimeMillis() - startTime) + "ms");
} catch (UnsatisfiedLinkError ex) {
Log.w(TAG, "Failed to load binary JNI connection! Error: " + ex.getMessage());
diff --git a/jnidictionaryv2/build.gradle b/jnidictionaryv2/build.gradle
index 7c6a094ed..7b119490e 100644
--- a/jnidictionaryv2/build.gradle
+++ b/jnidictionaryv2/build.gradle
@@ -1,24 +1,24 @@
apply plugin: 'com.android.library'
android {
- compileSdkVersion 21
- buildToolsVersion "21.1.2"
+ compileSdkVersion 22
+ buildToolsVersion "22.0.1"
defaultConfig {
minSdkVersion 7
- targetSdkVersion 21
+ targetSdkVersion 22
versionCode 1
versionName "1.0"
ndk {
moduleName "anysoftkey2_jni"
}
}
- buildTypes {
- release {
- minifyEnabled false
- }
- }
}
dependencies {
+ repositories {
+ mavenCentral()
+ }
+ compile 'net.evendanan.anysoftkeyboard:api:1.2.3'
+ compile project(':base')
}
diff --git a/src/main/java/com/anysoftkeyboard/dictionaries/jni/ResourceBinaryDictionary.java b/jnidictionaryv2/src/main/java/com/anysoftkeyboard/dictionaries/jni/ResourceBinaryDictionary.java
index aac12670c..9983c6c20 100644
--- a/src/main/java/com/anysoftkeyboard/dictionaries/jni/ResourceBinaryDictionary.java
+++ b/jnidictionaryv2/src/main/java/com/anysoftkeyboard/dictionaries/jni/ResourceBinaryDictionary.java
@@ -19,12 +19,11 @@ package com.anysoftkeyboard.dictionaries.jni;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
+import android.util.Log;
import com.anysoftkeyboard.base.dictionaries.Dictionary;
import com.anysoftkeyboard.base.dictionaries.WordComposer;
-import com.anysoftkeyboard.utils.IMEUtil.GCUtils;
-import com.anysoftkeyboard.utils.IMEUtil.GCUtils.MemRelatedOperation;
-import com.anysoftkeyboard.utils.Log;
+import com.anysoftkeyboard.base.utils.GCUtils;
import java.io.IOException;
import java.io.InputStream;
@@ -114,7 +113,7 @@ public class ResourceBinaryDictionary extends Dictionary {
a.recycle();
}
- GCUtils.getInstance().performOperationWithMemRetry(TAG, new MemRelatedOperation() {
+ GCUtils.getInstance().performOperationWithMemRetry(TAG, new GCUtils.MemRelatedOperation() {
public void operation() {
// The try-catch is for issue 878:
// http://code.google.com/p/softkeyboard/issues/detail?id=878
@@ -151,7 +150,7 @@ public class ResourceBinaryDictionary extends Dictionary {
if (got != total) {
Log.e(TAG, "Read " + got + " bytes, expected " + total);
} else {
- mNativeDict = openNative(mNativeDictDirectBuffer, TYPED_LETTER_MULTIPLIER, FULL_WORD_FREQ_MULTIPLIER);
+ mNativeDict = openNative(mNativeDictDirectBuffer, Dictionary.TYPED_LETTER_MULTIPLIER, Dictionary.FULL_WORD_FREQ_MULTIPLIER);
mDictLength = total;
}
} catch (IOException e) {
diff --git a/src/main/java/com/anysoftkeyboard/AnySoftKeyboard.java b/src/main/java/com/anysoftkeyboard/AnySoftKeyboard.java
index 2eeecf535..e52f94025 100644
--- a/src/main/java/com/anysoftkeyboard/AnySoftKeyboard.java
+++ b/src/main/java/com/anysoftkeyboard/AnySoftKeyboard.java
@@ -88,8 +88,8 @@ import com.anysoftkeyboard.theme.KeyboardThemeFactory;
import com.anysoftkeyboard.ui.VoiceInputNotInstalledActivity;
import com.anysoftkeyboard.ui.dev.DeveloperUtils;
import com.anysoftkeyboard.ui.settings.MainSettingsActivity;
-import com.anysoftkeyboard.utils.IMEUtil.GCUtils;
-import com.anysoftkeyboard.utils.IMEUtil.GCUtils.MemRelatedOperation;
+import com.anysoftkeyboard.base.utils.GCUtils;
+import com.anysoftkeyboard.base.utils.GCUtils.MemRelatedOperation;
import com.anysoftkeyboard.utils.Log;
import com.anysoftkeyboard.utils.ModifierKeyState;
import com.anysoftkeyboard.utils.Workarounds;
diff --git a/src/main/java/com/anysoftkeyboard/keyboards/views/AnyKeyboardBaseView.java b/src/main/java/com/anysoftkeyboard/keyboards/views/AnyKeyboardBaseView.java
index 7efc5374a..95b8ff0a5 100644
--- a/src/main/java/com/anysoftkeyboard/keyboards/views/AnyKeyboardBaseView.java
+++ b/src/main/java/com/anysoftkeyboard/keyboards/views/AnyKeyboardBaseView.java
@@ -71,8 +71,8 @@ import com.anysoftkeyboard.quicktextkeys.ui.QuickTextViewFactory;
import com.anysoftkeyboard.theme.KeyboardTheme;
import com.anysoftkeyboard.theme.KeyboardThemeFactory;
import com.anysoftkeyboard.utils.CompatUtils;
-import com.anysoftkeyboard.utils.IMEUtil.GCUtils;
-import com.anysoftkeyboard.utils.IMEUtil.GCUtils.MemRelatedOperation;
+import com.anysoftkeyboard.base.utils.GCUtils;
+import com.anysoftkeyboard.base.utils.GCUtils.MemRelatedOperation;
import com.anysoftkeyboard.utils.Log;
import com.menny.android.anysoftkeyboard.AnyApplication;
import com.menny.android.anysoftkeyboard.BuildConfig;
diff --git a/src/main/java/com/anysoftkeyboard/utils/EditingUtil.java b/src/main/java/com/anysoftkeyboard/utils/EditingUtil.java
deleted file mode 100644
index 77d99507e..000000000
--- a/src/main/java/com/anysoftkeyboard/utils/EditingUtil.java
+++ /dev/null
@@ -1,336 +0,0 @@
-///*
-// * Copyright (C) 2009 Google Inc.
-// *
-// * 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.
-// */
-//
-//package com.anysoftkeyboard.utils;
-//
-//import android.text.TextUtils;
-//import android.view.inputmethod.ExtractedText;
-//import android.view.inputmethod.ExtractedTextRequest;
-//import android.view.inputmethod.InputConnection;
-//
-//import java.lang.reflect.InvocationTargetException;
-//import java.lang.reflect.Method;
-//import java.util.regex.Pattern;
-//
-///**
-// * Utility methods to deal with editing text through an InputConnection.
-// */
-//public class EditingUtil {
-// /**
-// * Number of characters we want to look back in order to identify the previous word
-// */
-// private static final int LOOKBACK_CHARACTER_NUM = 15;
-//
-// // Cache Method pointers
-// private static boolean sMethodsInitialized;
-// private static Method sMethodGetSelectedText;
-// private static Method sMethodSetComposingRegion;
-//
-// private EditingUtil() {};
-//
-// /**
-// * Append newText to the text field represented by connection.
-// * The new text becomes selected.
-// */
-// public static void appendText(InputConnection connection, String newText) {
-// if (connection == null) {
-// return;
-// }
-//
-// // Commit the composing text
-// connection.finishComposingText();
-//
-// // Add a space if the field already has text.
-// CharSequence charBeforeCursor = connection.getTextBeforeCursor(1, 0);
-// if (charBeforeCursor != null
-// && !charBeforeCursor.equals(" ")
-// && (charBeforeCursor.length() > 0)) {
-// newText = " " + newText;
-// }
-//
-// connection.setComposingText(newText, 1);
-// }
-//
-// private static int getCursorPosition(InputConnection connection) {
-// ExtractedText extracted = connection.getExtractedText(
-// new ExtractedTextRequest(), 0);
-// if (extracted == null) {
-// return -1;
-// }
-// return extracted.startOffset + extracted.selectionStart;
-// }
-//
-// /**
-// * @param connection connection to the current text field.
-// * @param sep characters which may separate words
-// * @param range the range object to store the result into
-// * @return the word that surrounds the cursor, including up to one trailing
-// * separator. For example, if the field contains "he|llo world", where |
-// * represents the cursor, then "hello " will be returned.
-// */
-// public static String getWordAtCursor(
-// InputConnection connection, Range range) {
-// Range r = getWordRangeAtCursor(connection, range);
-// return (r == null) ? null : r.word;
-// }
-//
-// /**
-// * Removes the word surrounding the cursor. Parameters are identical to
-// * getWordAtCursor.
-// */
-// public static void deleteWordAtCursor(InputConnection connection) {
-//
-// Range range = getWordRangeAtCursor(connection, null);
-// if (range == null) return;
-//
-// connection.finishComposingText();
-// // Move cursor to beginning of word, to avoid crash when cursor is outside
-// // of valid range after deleting text.
-// int newCursor = getCursorPosition(connection) - range.charsBefore;
-// connection.setSelection(newCursor, newCursor);
-// connection.deleteSurroundingText(0, range.charsBefore + range.charsAfter);
-// }
-//
-// /**
-// * Represents a range of text, relative to the current cursor position.
-// */
-// public static class Range {
-// /** Characters before selection start */
-// public int charsBefore;
-//
-// /**
-// * Characters after selection start, including one trailing word
-// * separator.
-// */
-// public int charsAfter;
-//
-// /** The actual characters that make up a word */
-// public String word;
-//
-// public Range() {}
-//
-// public Range(int charsBefore, int charsAfter, String word) {
-// if (charsBefore < 0 || charsAfter < 0) {
-// throw new IndexOutOfBoundsException();
-// }
-// this.charsBefore = charsBefore;
-// this.charsAfter = charsAfter;
-// this.word = word;
-// }
-// }
-//
-// private static Range getWordRangeAtCursor(
-// InputConnection connection, Range range) {
-// if (connection == null) {
-// return null;
-// }
-// CharSequence before = connection.getTextBeforeCursor(1000, 0);
-// CharSequence after = connection.getTextAfterCursor(1000, 0);
-// if (before == null || after == null) {
-// return null;
-// }
-//
-// // Find first word separator before the cursor
-// int start = before.length();
-// while (start > 0 && !isWhitespace(before.charAt(start - 1))) start--;
-//
-// // Find last word separator after the cursor
-// int end = -1;
-// while (++end < after.length() && !isWhitespace(after.charAt(end)));
-//
-// int cursor = getCursorPosition(connection);
-// if (start >= 0 && cursor + end <= after.length() + before.length()) {
-// String word = before.toString().substring(start, before.length())
-// + after.toString().substring(0, end);
-//
-// Range returnRange = range != null? range : new Range();
-// returnRange.charsBefore = before.length() - start;
-// returnRange.charsAfter = end;
-// returnRange.word = word;
-// return returnRange;
-// }
-//
-// return null;
-// }
-//
-// private static boolean isWhitespace(int code) {
-// //return whitespace.contains(String.valueOf((char) code));
-// return !Character.isLetter((char)code);
-// }
-//
-// private static final Pattern spaceRegex = Pattern.compile("\\s+");
-//
-// public static CharSequence getPreviousWord(InputConnection connection,
-// String sentenceSeperators) {
-// //TODO: Should fix this. This could be slow!
-// CharSequence prev = connection.getTextBeforeCursor(LOOKBACK_CHARACTER_NUM, 0);
-// if (prev == null) {
-// return null;
-// }
-// String[] w = spaceRegex.split(prev);
-// if (w.length >= 2 && w[w.length-2].length() > 0) {
-// char lastChar = w[w.length-2].charAt(w[w.length-2].length() -1);
-// if (sentenceSeperators.contains(String.valueOf(lastChar))) {
-// return null;
-// }
-// return w[w.length-2];
-// } else {
-// return null;
-// }
-// }
-//
-// public static class SelectedWord {
-// public int start;
-// public int end;
-// public CharSequence word;
-// }
-//
-// /**
-// * Takes a character sequence with a single character and checks if the character occurs
-// * in a list of word separators or is empty.
-// * @param singleChar A CharSequence with null, zero or one character
-// * @param wordSeparators A String containing the word separators
-// * @return true if the character is at a word boundary, false otherwise
-// */
-// private static boolean isWordBoundary(CharSequence singleChar) {
-// return TextUtils.isEmpty(singleChar) || isWhitespace(singleChar.charAt(0));
-// }
-//
-// /**
-// * Checks if the cursor is inside a word or the current selection is a whole word.
-// * @param ic the InputConnection for accessing the text field
-// * @param selStart the start position of the selection within the text field
-// * @param selEnd the end position of the selection within the text field. This could be
-// * the same as selStart, if there's no selection.
-// * @param wordSeparators the word separator characters for the current language
-// * @return an object containing the text and coordinates of the selected/touching word,
-// * null if the selection/cursor is not marking a whole word.
-// */
-// public static SelectedWord getWordAtCursorOrSelection(final InputConnection ic, int selStart, int selEnd) {
-// if (selStart == selEnd) {
-// // There is just a cursor, so get the word at the cursor
-// EditingUtil.Range range = new EditingUtil.Range();
-// CharSequence touching = getWordAtCursor(ic, range);
-// if (!TextUtils.isEmpty(touching)) {
-// SelectedWord selWord = new SelectedWord();
-// selWord.word = touching;
-// selWord.start = selStart - range.charsBefore;
-// selWord.end = selEnd + range.charsAfter;
-// return selWord;
-// }
-// } else {
-// // Is the previous character empty or a word separator? If not, return null.
-// CharSequence charsBefore = ic.getTextBeforeCursor(1, 0);
-// if (!isWordBoundary(charsBefore)) {
-// return null;
-// }
-//
-// // Is the next character empty or a word separator? If not, return null.
-// CharSequence charsAfter = ic.getTextAfterCursor(1, 0);
-// if (!isWordBoundary(charsAfter)) {
-// return null;
-// }
-//
-// // Extract the selection alone
-// CharSequence touching = getSelectedText(ic, selStart, selEnd);
-// if (TextUtils.isEmpty(touching)) return null;
-// // Is any part of the selection a separator? If so, return null.
-// final int length = touching.length();
-// for (int i = 0; i < length; i++) {
-// if (isWhitespace(touching.subSequence(i, i + 1).charAt(0))) {
-// return null;
-// }
-// }
-// // Prepare the selected word
-// SelectedWord selWord = new SelectedWord();
-// selWord.start = selStart;
-// selWord.end = selEnd;
-// selWord.word = touching;
-// return selWord;
-// }
-// return null;
-// }
-//
-//// /**
-//// * Cache method pointers for performance
-//// */
-//// private static void initializeMethodsForReflection() {
-//// try {
-//// // These will either both exist or not, so no need for separate try/catch blocks.
-//// // If other methods are added later, use separate try/catch blocks.
-//// sMethodGetSelectedText = InputConnection.class.getMethod("getSelectedText", int.class);
-//// sMethodSetComposingRegion = InputConnection.class.getMethod("setComposingRegion",
-//// int.class, int.class);
-//// } catch (NoSuchMethodException exc) {
-//// // Ignore
-//// }
-//// sMethodsInitialized = true;
-//// }
-////
-//// /**
-//// * Returns the selected text between the selStart and selEnd positions.
-//// */
-//// private static CharSequence getSelectedText(InputConnection ic, int selStart, int selEnd) {
-//// // Use reflection, for backward compatibility
-//// CharSequence result = null;
-//// if (!sMethodsInitialized) {
-//// initializeMethodsForReflection();
-//// }
-//// if (sMethodGetSelectedText != null) {
-//// try {
-//// result = (CharSequence) sMethodGetSelectedText.invoke(ic, 0);
-//// return result;
-//// } catch (InvocationTargetException exc) {
-//// // Ignore
-//// } catch (IllegalArgumentException e) {
-//// // Ignore
-//// } catch (IllegalAccessException e) {
-//// // Ignore
-//// }
-//// }
-//// // Reflection didn't work, try it the poor way, by moving the cursor to the start,
-//// // getting the text after the cursor and moving the text back to selected mode.
-//// // TODO: Verify that this works properly in conjunction with
-//// // LatinIME#onUpdateSelection
-//// ic.setSelection(selStart, selEnd);
-//// result = ic.getTextAfterCursor(selEnd - selStart, 0);
-//// ic.setSelection(selStart, selEnd);
-//// return result;
-//// }
-//
-//// /**
-//// * Tries to set the text into composition mode if there is support for it in the framework.
-//// */
-//// public static void underlineWord(InputConnection ic, SelectedWord word) {
-//// // Use reflection, for backward compatibility
-//// // If method not found, there's nothing we can do. It still works but just wont underline
-//// // the word.
-//// if (!sMethodsInitialized) {
-//// initializeMethodsForReflection();
-//// }
-//// if (sMethodSetComposingRegion != null) {
-//// try {
-//// sMethodSetComposingRegion.invoke(ic, word.start, word.end);
-//// } catch (InvocationTargetException exc) {
-//// // Ignore
-//// } catch (IllegalArgumentException e) {
-//// // Ignore
-//// } catch (IllegalAccessException e) {
-//// // Ignore
-//// }
-//// }
-//// }
-//} \ No newline at end of file
diff --git a/src/main/java/com/anysoftkeyboard/utils/IMEUtil.java b/src/main/java/com/anysoftkeyboard/utils/IMEUtil.java
index c0bf46253..5ad9cb280 100644
--- a/src/main/java/com/anysoftkeyboard/utils/IMEUtil.java
+++ b/src/main/java/com/anysoftkeyboard/utils/IMEUtil.java
@@ -175,64 +175,6 @@ public class IMEUtil {
}*/
}
- public static class GCUtils {
- 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.
- 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 performOperationWithMemRetry(String TAG, MemRelatedOperation operation, boolean failWithException) {
- reset();
-
- boolean retry = true;
- while (retry) {
- try {
- 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;
- }
-
- private void reset() {
- mGCTryCount = 0;
- }
-
- private boolean tryGCOrWait(String metaData, Throwable t) {
- if (mGCTryCount % GC_TRY_COUNT == 0) {
- System.gc();
- }
- if (mGCTryCount > GC_TRY_LOOP_MAX) {
- return false;
- } else {
- mGCTryCount++;
- try {
- Thread.sleep(GC_INTERVAL);
- return true;
- } catch (InterruptedException e) {
- Log.e(metaData, "Sleep was interrupted.");
- //ImeLogger.logOnException(metaData, t);
- return false;
- }
- }
- }
-
- public static interface MemRelatedOperation {
- void operation();
- }
- }
-
/* package */ static class RingCharBuffer {
/* package */ static final int BUFSIZE = 20;
private static final char PLACEHOLDER_DELIMITER_CHAR = '\uFFFC';