diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index e0adc9a7121084700f0f42ab773e67a425ebcee8..6ac6e83a38cdd037f92f197c7825cac003b96bca 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -88,17 +88,15 @@ public class BinaryDictionary extends Dictionary {
             int typedLetterMultiplier, int fullWordMultiplier, int maxWordLength, int maxWords,
             int maxPredictions);
     private native void closeNative(long dict);
-    private native int getFrequencyNative(long dict, int[] word, int wordLength);
+    private native int getFrequencyNative(long dict, int[] word);
     private native boolean isValidBigramNative(long dict, int[] word1, int[] word2);
     private native int getSuggestionsNative(long dict, long proximityInfo, long traverseSession,
             int[] xCoordinates, int[] yCoordinates, int[] times, int[] pointerIds,
             int[] inputCodes, int codesSize, int commitPoint, boolean isGesture,
             int[] prevWordCodePointArray, boolean useFullEditDistance, char[] outputChars,
             int[] outputScores, int[] outputIndices, int[] outputTypes);
-    private static native float calcNormalizedScoreNative(
-            char[] before, int beforeLength, char[] after, int afterLength, int score);
-    private static native int editDistanceNative(
-            char[] before, int beforeLength, char[] after, int afterLength);
+    private static native float calcNormalizedScoreNative(char[] before, char[] after, int score);
+    private static native int editDistanceNative(char[] before, char[] after);
 
     private final void loadDictionary(String path, long startOffset, long length) {
         mNativeDict = openNative(path, startOffset, length, TYPED_LETTER_MULTIPLIER,
@@ -158,13 +156,11 @@ public class BinaryDictionary extends Dictionary {
     }
 
     public static float calcNormalizedScore(String before, String after, int score) {
-        return calcNormalizedScoreNative(before.toCharArray(), before.length(),
-                after.toCharArray(), after.length(), score);
+        return calcNormalizedScoreNative(before.toCharArray(), after.toCharArray(), score);
     }
 
     public static int editDistance(String before, String after) {
-        return editDistanceNative(
-                before.toCharArray(), before.length(), after.toCharArray(), after.length());
+        return editDistanceNative(before.toCharArray(), after.toCharArray());
     }
 
     @Override
@@ -175,8 +171,8 @@ public class BinaryDictionary extends Dictionary {
     @Override
     public int getFrequency(CharSequence word) {
         if (word == null) return -1;
-        int[] chars = StringUtils.toCodePointArray(word.toString());
-        return getFrequencyNative(mNativeDict, chars, chars.length);
+        int[] codePoints = StringUtils.toCodePointArray(word.toString());
+        return getFrequencyNative(mNativeDict, codePoints);
     }
 
     // TODO: Add a batch process version (isValidBigramMultiple?) to avoid excessive numbers of jni
diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
index 6e2efbec16583e9410f71e91c52188a6418afd60..1596a636d96910148c31fb0c2ea04d49e5806406 100644
--- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
+++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
@@ -172,53 +172,54 @@ static int latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jobject object,
 }
 
 static jint latinime_BinaryDictionary_getFrequency(JNIEnv *env, jobject object, jlong dict,
-        jintArray wordArray, jint wordLength) {
-    Dictionary *dictionary = (Dictionary*)dict;
-    if (!dictionary) return (jboolean) false;
-    jint *word = env->GetIntArrayElements(wordArray, 0);
-    jint result = dictionary->getFrequency(word, wordLength);
-    env->ReleaseIntArrayElements(wordArray, word, JNI_ABORT);
-    return result;
+        jintArray wordArray) {
+    Dictionary *dictionary = reinterpret_cast<Dictionary*>(dict);
+    if (!dictionary) return 0;
+    const jsize codePointLength = env->GetArrayLength(wordArray);
+    int codePoints[codePointLength];
+    env->GetIntArrayRegion(wordArray, 0, codePointLength, codePoints);
+    return dictionary->getFrequency(codePoints, codePointLength);
 }
 
 static jboolean latinime_BinaryDictionary_isValidBigram(JNIEnv *env, jobject object, jlong dict,
         jintArray wordArray1, jintArray wordArray2) {
-    Dictionary *dictionary = (Dictionary*)dict;
+    Dictionary *dictionary = reinterpret_cast<Dictionary*>(dict);
     if (!dictionary) return (jboolean) false;
-    jint *word1 = env->GetIntArrayElements(wordArray1, 0);
-    jint *word2 = env->GetIntArrayElements(wordArray2, 0);
-    jsize length1 = word1 ? env->GetArrayLength(wordArray1) : 0;
-    jsize length2 = word2 ? env->GetArrayLength(wordArray2) : 0;
-    jboolean result = dictionary->isValidBigram(word1, length1, word2, length2);
-    env->ReleaseIntArrayElements(wordArray2, word2, JNI_ABORT);
-    env->ReleaseIntArrayElements(wordArray1, word1, JNI_ABORT);
-    return result;
+    const jsize codePointLength1 = env->GetArrayLength(wordArray1);
+    const jsize codePointLength2 = env->GetArrayLength(wordArray2);
+    int codePoints1[codePointLength1];
+    int codePoints2[codePointLength2];
+    env->GetIntArrayRegion(wordArray1, 0, codePointLength1, codePoints1);
+    env->GetIntArrayRegion(wordArray2, 0, codePointLength2, codePoints2);
+    return dictionary->isValidBigram(codePoints1, codePointLength1, codePoints2, codePointLength2);
 }
 
 static jfloat latinime_BinaryDictionary_calcNormalizedScore(JNIEnv *env, jobject object,
-        jcharArray before, jint beforeLength, jcharArray after, jint afterLength, jint score) {
-    jchar *beforeChars = env->GetCharArrayElements(before, 0);
-    jchar *afterChars = env->GetCharArrayElements(after, 0);
-    jfloat result = Correction::RankingAlgorithm::calcNormalizedScore((unsigned short*)beforeChars,
+        jcharArray before, jcharArray after, jint score) {
+    jsize beforeLength = env->GetArrayLength(before);
+    jsize afterLength = env->GetArrayLength(after);
+    jchar beforeChars[beforeLength];
+    jchar afterChars[afterLength];
+    env->GetCharArrayRegion(before, 0, beforeLength, beforeChars);
+    env->GetCharArrayRegion(after, 0, afterLength, afterChars);
+    return Correction::RankingAlgorithm::calcNormalizedScore((unsigned short*)beforeChars,
             beforeLength, (unsigned short*)afterChars, afterLength, score);
-    env->ReleaseCharArrayElements(after, afterChars, JNI_ABORT);
-    env->ReleaseCharArrayElements(before, beforeChars, JNI_ABORT);
-    return result;
 }
 
 static jint latinime_BinaryDictionary_editDistance(JNIEnv *env, jobject object,
-        jcharArray before, jint beforeLength, jcharArray after, jint afterLength) {
-    jchar *beforeChars = env->GetCharArrayElements(before, 0);
-    jchar *afterChars = env->GetCharArrayElements(after, 0);
-    jint result = Correction::RankingAlgorithm::editDistance(
-            (unsigned short*)beforeChars, beforeLength, (unsigned short*)afterChars, afterLength);
-    env->ReleaseCharArrayElements(after, afterChars, JNI_ABORT);
-    env->ReleaseCharArrayElements(before, beforeChars, JNI_ABORT);
-    return result;
+        jcharArray before, jcharArray after) {
+    jsize beforeLength = env->GetArrayLength(before);
+    jsize afterLength = env->GetArrayLength(after);
+    jchar beforeChars[beforeLength];
+    jchar afterChars[afterLength];
+    env->GetCharArrayRegion(before, 0, beforeLength, beforeChars);
+    env->GetCharArrayRegion(after, 0, afterLength, afterChars);
+    return Correction::RankingAlgorithm::editDistance((unsigned short*)beforeChars, beforeLength,
+            (unsigned short*)afterChars, afterLength);
 }
 
 static void latinime_BinaryDictionary_close(JNIEnv *env, jobject object, jlong dict) {
-    Dictionary *dictionary = (Dictionary*)dict;
+    Dictionary *dictionary = reinterpret_cast<Dictionary*>(dict);
     if (!dictionary) return;
     void *dictBuf = dictionary->getDict();
     if (!dictBuf) return;
@@ -251,11 +252,11 @@ static JNINativeMethod sMethods[] = {
     {"closeNative", "(J)V", (void*)latinime_BinaryDictionary_close},
     {"getSuggestionsNative", "(JJJ[I[I[I[I[IIIZ[IZ[C[I[I[I)I",
             (void*) latinime_BinaryDictionary_getSuggestions},
-    {"getFrequencyNative", "(J[II)I", (void*)latinime_BinaryDictionary_getFrequency},
+    {"getFrequencyNative", "(J[I)I", (void*)latinime_BinaryDictionary_getFrequency},
     {"isValidBigramNative", "(J[I[I)Z", (void*)latinime_BinaryDictionary_isValidBigram},
-    {"calcNormalizedScoreNative", "([CI[CII)F",
+    {"calcNormalizedScoreNative", "([C[CI)F",
             (void*)latinime_BinaryDictionary_calcNormalizedScore},
-    {"editDistanceNative", "([CI[CI)I", (void*)latinime_BinaryDictionary_editDistance}
+    {"editDistanceNative", "([C[C)I", (void*)latinime_BinaryDictionary_editDistance}
 };
 
 int register_BinaryDictionary(JNIEnv *env) {