android jni

21
Android Hackathon 2009.3.20 Android JNI 餃子のまち 宇都宮 村沢 邦夫

Upload: kunio-murasawa

Post on 14-Dec-2014

14.941 views

Category:

Technology


7 download

DESCRIPTION

Android Hackathon 2009.3.20

TRANSCRIPT

Page 1: Android JNI

Android Hackathon 2009.3.20

Android で JNI

餃子のまち 宇都宮

村沢 邦夫

Page 2: Android JNI

必要なもの• Android SDK

– 1.1_r1で試してます

• Eclipse• android.git.kernel.org より

– toolchain• C コンパイラ arm-eabi-gcc など

– bionic• C ライブラリ / ヘッダファイル

• glibc でない

• Dynamic Linker / Loader も独自

– dalvik• jni.h

Page 3: Android JNI

準備

• Android のソースを取得してビルド– 手順は次の URL に詳しく書いてあります

– http://source.android.com/download– 実行環境に合わせてブランチを選んでね

• 2009.3.14頃の master で試してます

• ビルドされたモノは /xxx/out に出来る– /xxx は Android ソースを置いたディレクトリ

– /xxx は自分の環境に合わせて直してね

Page 4: Android JNI

ツールチェイン

• 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

Page 5: Android JNI

ライブラリ

• Android 用ライブラリ

• 必要に応じてライブラリパスに設定– /xxx/out/target/product/generic/obj/lib

Page 6: Android JNI

ヘッダファイル

• Android 用ヘッダファイル

• 必要に応じてインクルードパスに設定– /xxx/bionic/libc/include– /xxx/bionic/libc/kernel/arch-arm– /xxx/libc/arch-arm/include– /xxx/kernel/include

Page 7: Android JNI

JNI

• Android 用 JNI ヘッダファイル

• インクルードパスに設定– /xxx/dalvik/libnativehelper/include/nativehelper

Page 8: Android JNI

その他(1)

• リンカスクリプト(shared library 用)– /xxx/build/core/armelf.xsc

• Dynamic Linker / Loader– /system/bin/linker

• Android のライブラリ置き場 (LD_LIBRARY_PATH)

– /system/lib

Page 9: Android JNI

その他(2)

• agcc

– http://plausible.org/andy/agcc– コンパイル用スクリプト

– ライブラリ、インクルードパス等を自動で設定してくれるので便利

– 以降、コンパイルは agcc を使って説明

Page 10: Android JNI

JNI 作成手順

① Java コード作成

② クラスファイル生成

③ C / C++ 用ヘッダファイル生成

④ C / C++ コード作成

⑤ 共有ライブラリ生成

Page 11: Android JNI

JNI で Hello World

• HelloWorld クラスを作成– パッケージ名 jni_test.helloWorldJNI

• ネイティブメソッドとして get を用意– 「Hello JNI World」の文字列を返す

• ネイティブライブラリは libHelloWorld.so とする– ソースは HelloWorld.c

• Activity は HelloWorldJNI とし HelloWorld クラスの get メソッドで文字列を取得し表示

Page 12: Android JNI

① Java コード作成 HelloWorld.java

package jni_test.helloWorldJNI;

public class HelloWorld {static {

System.loadLibrary("HelloWorld");}

public native String get();}

※System.loadLibrary で libHelloWorld.so をロード※ネイティブメソッドには native キーワードをつける

Page 13: Android JNI

② クラスファイル生成HelloWorld.class

• Eclipse でコンパイルすればOK• コマンドラインでやるなら

$ javac jni_test/helloWorldJNI/HelloWorld.java

Page 14: Android JNI

③ C / C++ 用ヘッダファイル生成jni_test_helloWorldJNI_HelloWorld.h

$ javah jni_test.helloWorldJNI.HelloWorld

• javah コマンドで生成– クラスファイルからヘッダファイルを生成

– jni_test_helloWorldJNI_HelloWorld.h– C / C++ コードでインクルード

• Eclipse からやる方法は知らない(汗)

Page 15: Android JNI

生成されたヘッダファイル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 __cplusplusextern "C" {#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

Page 16: Android JNI

④ C / C++ コード作成HelloWorld.c

#include "jni_test_helloWorldJNI_HelloWorld.h"

JNIEXPORT jstring JNICALL Java_jni_1test_helloWorldJNI_HelloWorld_get(JNIEnv *env, jobject obj){ return (*env)->NewStringUTF(env, "Hello JNI World");}

• HelloWorld.c を作成– 先程生成したヘッダファイルをベースに

– get メソッドに対応する部分を実装• Java_jni_helloWolrdJNI_HelloWorld_get

Page 17: Android JNI

⑤ 共有ライブラリ生成libHelloWorld.so

$ agcc -shared -fPIC HelloWorld.c -o libHelloWorld.so -I/xxx/dalvik/libnativehelper/include/nativehelper

※実際は1行。Eclipse からやる方法は知らない(汗)

• HelloWorld.c から libHelloWorld.so を作る● agcc を使ってコンパイル● shared オプションを付けて共有ライブラリに● インクルードパスに jni.h の在処を指定

Page 18: Android JNI

共有ライブラリを転送

$ adb shell# mount -o rw,remount /dev/block/mtdblock3 /system# exit$ adb push libHelloWorld.so /system/lib

※実機の場合は未確認 ・端末屋さんならルートファイルシステムに入れておけばいいよね ・アプリ屋さんなら jar ファイルに入れて配布? → so ファイルを取り出して LD_LIBRARY_PATH に設定かな?

• Android に libHelloWorld.so を転送– /system/lib– Read only なので R/W に変更

Page 19: Android JNI

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); }}

Page 20: Android JNI

実行結果

Page 21: Android JNI

おわり