Welcome to FutureAppLaboratory

v=(*^ワ^*)=v

Mozc完全解説02

| Comments

はじめに

前回では、android側からタッチ反応を発生してから、jniを通して変換エンジンのnative側が候補を返すまでを説明した。
今回ではjni部分のコードを少し説明する。

What is jni?

言わばjavaとc, cppとの間のインターフェイスですね。cやcppを使って、java側とデータのやり取りができる。
Java Native Interface

mozcに使われているjni

java側ではMozcJNI.javaというラッパーがある。メソッドはこの通り。

  • load(String, Buffer, Buffer, String)
    初期化用のメソッド、apkの中に入っている辞書データなどをnative側に渡す
  • evalCommand(byte[])
    native側と通信するメソッド、jniで実装
  • onPostLoad(String, Buffer, Buffer)
    loadメソッドに使われている、jniで実装
  • getVersion()
    native側のバージョン情報をjava側に渡す。loadメソッドに使われている、jniで実装

jniの実装ファイルはjni/mozcjni.cc。では、evalCommand(byte[])を詳しく見てみよう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// ------> この矢印のあたりは、私の追加したコメントです
jbyteArray JNICALL evalCommand(JNIEnv *env, jclass clazz, jbyteArray in_bytes_array) {
  jboolean is_copy = false;
  jbyte *in_bytes = env->GetByteArrayElements(in_bytes_array, &is_copy);
  const jsize in_size = env->GetArrayLength(in_bytes_array);

  // ------> commandにパースする。session/commands.protoにはcommandの定義が書かれいる。
  // ------> protobuf(Protocol Buffers)というライブラリを使っています。
  mozc::commands::Command command;
  command.ParseFromArray(in_bytes, in_size);

  // ------> native側でcommandを処理する。結果はcommandの中に格納する。
  mozc::Singleton<SessionHandlerSingletonAdapter>::get()->getHandler()
      ->EvalCommand(&command);

  // Use JNI_ABORT because in_bytes is read only.
  // ------> JNI_ABORT: 要素列をJava配列に反映させず、要素列バッファを解放する。
  env->ReleaseByteArrayElements(in_bytes_array, in_bytes, JNI_ABORT);

  // 変換結果はjbyteArrayとしてjava側に返す
  const int out_size = command.ByteSize();
  jbyteArray out_bytes_array = env->NewByteArray(out_size);


  // ------> is_copy: 0の場合、生成された配列(out_bytes)を変更すると、java側にも変更される。
  //                  1の場合、変更してもjava側には変更されない。
  jbyte *out_bytes = env->GetByteArrayElements(out_bytes_array, &is_copy);
  command.SerializeToArray(out_bytes, out_size);

  // Use 0 to copy out_bytes to out_bytes_array.
  // ------> 0の場合、要素列をJava配列に反映させ、要素列バッファを解放する。
  env->ReleaseByteArrayElements(out_bytes_array, out_bytes, 0);

  return out_bytes_array;
}

in_bytes_arrayには、タッチされたキーの情報などが入っている。
out_bytes_arrayには、変換候補などが入っている。
前回最後のlog部分を参考してくだい。

終わりに

jni側の実装に関する説明はここまで。
次回ではevalCommandメソッドをもっと細かく説明する。

Comments