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

Android JNI

Dec 14, 2014

Download

Technology

Kunio Murasawa

Android Hackathon 2009.3.20
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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

おわり