Android JNI

15,315 views
15,150 views

Published on

Android Hackathon 2009.3.20

Published in: Technology
1 Comment
7 Likes
Statistics
Notes
  • Android で JNI
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
15,315
On SlideShare
0
From Embeds
0
Number of Embeds
1,350
Actions
Shares
0
Downloads
105
Comments
1
Likes
7
Embeds 0
No embeds

No notes for slide

Android JNI

  1. 1. Android Hackathon 2009.3.20 Android で JNI 餃子のまち 宇都宮 村沢 邦夫
  2. 2. 必要なもの • Android SDK – 1.1_r1で試してます • Eclipse • android.git.kernel.org より – toolchain • C コンパイラ arm-eabi-gcc など – bionic • C ライブラリ / ヘッダファイル • glibc でない • Dynamic Linker / Loader も独自 – dalvik • jni.h
  3. 3. 準備 • Android のソースを取得してビルド – 手順は次の URL に詳しく書いてあります – http://source.android.com/download – 実行環境に合わせてブランチを選んでね • 2009.3.14頃の master で試してます • ビルドされたモノは /xxx/out に出来る – /xxx は Android ソースを置いたディレクトリ – /xxx は自分の環境に合わせて直してね
  4. 4. ツールチェイン • Android クロス開発用 toolchain – arm-eabi-gcc コマンド等 • 環境変数 PATH に設定 – /xxx/prebuilt/darwin-x86/toolchain/arm-eabi-4.2.1/bin – 自分の環境に合わせて darwin-x86 の部分は直してね • Mac OS X は darwin-x86 • Linux は linux-x86 • Windows は windows
  5. 5. ライブラリ • Android 用ライブラリ • 必要に応じてライブラリパスに設定 – /xxx/out/target/product/generic/obj/lib
  6. 6. ヘッダファイル • Android 用ヘッダファイル • 必要に応じてインクルードパスに設定 – /xxx/bionic/libc/include – /xxx/bionic/libc/kernel/arch-arm – /xxx/libc/arch-arm/include – /xxx/kernel/include
  7. 7. JNI • Android 用 JNI ヘッダファイル • インクルードパスに設定 – /xxx/dalvik/libnativehelper/include/nativehelper
  8. 8. その他(1) • リンカスクリプト(shared library 用) – /xxx/build/core/armelf.xsc • Dynamic Linker / Loader – /system/bin/linker • Android のライブラリ置き場 (LD_LIBRARY_PATH) – /system/lib
  9. 9. その他(2) • agcc – http://plausible.org/andy/agcc – コンパイル用スクリプト – ライブラリ、インクルードパス等を自動で設 定してくれるので便利 – 以降、コンパイルは agcc を使って説明
  10. 10. JNI 作成手順 ① Java コード作成 ② クラスファイル生成 ③ C / C++ 用ヘッダファイル生成 ④ C / C++ コード作成 ⑤ 共有ライブラリ生成
  11. 11. JNI で Hello World • HelloWorld クラスを作成 – パッケージ名 jni_test.helloWorldJNI • ネイティブメソッドとして get を用意 – 「Hello JNI World」の文字列を返す • ネイティブライブラリは libHelloWorld.so とする – ソースは HelloWorld.c • Activity は HelloWorldJNI とし HelloWorld クラス の get メソッドで文字列を取得し表示
  12. 12. ① Java コード作成 HelloWorld.java package jni_test.helloWorldJNI; public class HelloWorld { static { System.loadLibrary(quot;HelloWorldquot;); } public native String get(); } ※System.loadLibrary で libHelloWorld.so をロード ※ネイティブメソッドには native キーワードをつける
  13. 13. ② クラスファイル生成 HelloWorld.class • Eclipse でコンパイルすればOK • コマンドラインでやるなら $ javac jni_test/helloWorldJNI/HelloWorld.java
  14. 14. ③ C / C++ 用ヘッダファイル生成 jni_test_helloWorldJNI_HelloWorld.h • javah コマンドで生成 – クラスファイルからヘッダファイルを生成 – jni_test_helloWorldJNI_HelloWorld.h – C / C++ コードでインクルード • Eclipse からやる方法は知らない(汗) $ javah jni_test.helloWorldJNI.HelloWorld
  15. 15. 生成されたヘッダファイル jni_test_helloWorldJNI_HelloWorld.h /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class jni_test_helloWorldJNI_HelloWorld */ #ifndef _Included_jni_test_helloWorldJNI_HelloWorld #define _Included_jni_test_helloWorldJNI_HelloWorld #ifdef __cplusplus extern quot;Cquot; { #endif /* * Class: jni_test_helloWorldJNI_HelloWorld * Method: get * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_jni_1test_helloWorldJNI_HelloWorld_get (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
  16. 16. ④ C / C++ コード作成 HelloWorld.c • HelloWorld.c を作成 – 先程生成したヘッダファイルをベースに – get メソッドに対応する部分を実装 • Java_jni_helloWolrdJNI_HelloWorld_get #include quot;jni_test_helloWorldJNI_HelloWorld.hquot; JNIEXPORT jstring JNICALL Java_jni_1test_helloWorldJNI_HelloWorld_get(JNIEnv *env, jobject obj) { return (*env)->NewStringUTF(env, quot;Hello JNI Worldquot;); }
  17. 17. ⑤ 共有ライブラリ生成 libHelloWorld.so • HelloWorld.c から libHelloWorld.so を作る agcc を使ってコンパイル ● ● shared オプションを付けて共有ライブラリに ● インクルードパスに jni.h の在処を指定 $ agcc -shared -fPIC HelloWorld.c -o libHelloWorld.so -I/xxx/dalvik/libnativehelper/include/nativehelper ※実際は1行。Eclipse からやる方法は知らない(汗)
  18. 18. 共有ライブラリを転送 • Android に libHelloWorld.so を転送 – /system/lib – Read only なので R/W に変更 $ adb shell # mount -o rw,remount /dev/block/mtdblock3 /system # exit $ adb push libHelloWorld.so /system/lib ※実機の場合は未確認  ・端末屋さんならルートファイルシステムに入れておけばいいよね ・アプリ屋さんなら jar ファイルに入れて配布? → so ファイルを取り出して LD_LIBRARY_PATH に設定かな?
  19. 19. HelloWorld のテストコード HelloWorldJNI.java package jni_test.helloWorldJNI; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class HelloWorldJNI extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); TextView tv = new TextView(this); tv.setText(new HelloWorld().get()); setContentView(tv); } }
  20. 20. 実行結果
  21. 21. おわり

×