SlideShare uma empresa Scribd logo
1 de 21
Baixar para ler offline
Android Hackathon 2009.3.20
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
準備
• Android のソースを取得してビルド
   – 手順は次の URL に詳しく書いてあります
   – http://source.android.com/download
   – 実行環境に合わせてブランチを選んでね
         • 2009.3.14頃の master で試してます
• ビルドされたモノは /xxx/out に出来る
   – /xxx は Android ソースを置いたディレクトリ
   – /xxx は自分の環境に合わせて直してね
ツールチェイン
• 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
ライブラリ
• Android 用ライブラリ
• 必要に応じてライブラリパスに設定
  – /xxx/out/target/product/generic/obj/lib
ヘッダファイル
• Android 用ヘッダファイル
• 必要に応じてインクルードパスに設定
  –   /xxx/bionic/libc/include
  –   /xxx/bionic/libc/kernel/arch-arm
  –   /xxx/libc/arch-arm/include
  –   /xxx/kernel/include
JNI
• Android 用 JNI ヘッダファイル
• インクルードパスに設定
   – /xxx/dalvik/libnativehelper/include/nativehelper
その他(1)
• リンカスクリプト(shared library 用)
     – /xxx/build/core/armelf.xsc
• Dynamic Linker / Loader
     – /system/bin/linker
• Android のライブラリ置き場                 (LD_LIBRARY_PATH)
     – /system/lib
その他(2)
• agcc
     – http://plausible.org/andy/agcc
     – コンパイル用スクリプト
     – ライブラリ、インクルードパス等を自動で設
       定してくれるので便利
     – 以降、コンパイルは agcc を使って説明
JNI 作成手順
① Java コード作成
② クラスファイル生成
③ C / C++ 用ヘッダファイル生成
④ C / C++ コード作成
⑤ 共有ライブラリ生成
JNI で Hello World
• HelloWorld クラスを作成
     – パッケージ名 jni_test.helloWorldJNI
• ネイティブメソッドとして get を用意
     – 「Hello JNI World」の文字列を返す
• ネイティブライブラリは libHelloWorld.so とする
     – ソースは HelloWorld.c
• Activity は HelloWorldJNI とし HelloWorld クラス
  の get メソッドで文字列を取得し表示
① Java コード作成
                      HelloWorld.java

 package jni_test.helloWorldJNI;

 public class HelloWorld {
    static {
         System.loadLibrary(quot;HelloWorldquot;);
    }

     public native String get();
 }


※System.loadLibrary で libHelloWorld.so をロード
※ネイティブメソッドには native キーワードをつける
② クラスファイル生成
                 HelloWorld.class


• Eclipse でコンパイルすればOK
• コマンドラインでやるなら
   $ javac jni_test/helloWorldJNI/HelloWorld.java
③ C / C++ 用ヘッダファイル生成
           jni_test_helloWorldJNI_HelloWorld.h

• javah コマンドで生成
     – クラスファイルからヘッダファイルを生成
     – jni_test_helloWorldJNI_HelloWorld.h
     – C / C++ コードでインクルード
• Eclipse からやる方法は知らない(汗)

$ javah jni_test.helloWorldJNI.HelloWorld
生成されたヘッダファイル
                 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
④ 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;);
}
⑤ 共有ライブラリ生成
                    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 からやる方法は知らない(汗)
共有ライブラリを転送
• 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 に設定かな?
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);
    }
}
実行結果
おわり

Mais conteúdo relacionado

Mais procurados

Web技術勉強会12回目
Web技術勉強会12回目Web技術勉強会12回目
Web技術勉強会12回目
龍一 田中
 
Ohp Seijoen H20 08 Jfreechart
Ohp Seijoen H20 08 JfreechartOhp Seijoen H20 08 Jfreechart
Ohp Seijoen H20 08 Jfreechart
sesejun
 
Readme ko
Readme koReadme ko
Readme ko
Thata22
 
智慧型手機
智慧型手機智慧型手機
智慧型手機
Kelun Yang
 

Mais procurados (17)

Web技術勉強会12回目
Web技術勉強会12回目Web技術勉強会12回目
Web技術勉強会12回目
 
Personal knowledge management
Personal knowledge managementPersonal knowledge management
Personal knowledge management
 
97th Kernel code reading party, TOMOYO Linux Night
97th Kernel code reading party, TOMOYO Linux Night97th Kernel code reading party, TOMOYO Linux Night
97th Kernel code reading party, TOMOYO Linux Night
 
S20
S20S20
S20
 
유기화학 2nd
유기화학 2nd유기화학 2nd
유기화학 2nd
 
用Pootle翻譯OLPC專案
用Pootle翻譯OLPC專案用Pootle翻譯OLPC專案
用Pootle翻譯OLPC專案
 
Ohp Seijoen H20 08 Jfreechart
Ohp Seijoen H20 08 JfreechartOhp Seijoen H20 08 Jfreechart
Ohp Seijoen H20 08 Jfreechart
 
Readme ko
Readme koReadme ko
Readme ko
 
Programming言語Lua紹介(Internet版)
Programming言語Lua紹介(Internet版)Programming言語Lua紹介(Internet版)
Programming言語Lua紹介(Internet版)
 
Streaming of Huxley
Streaming of HuxleyStreaming of Huxley
Streaming of Huxley
 
智慧型手機
智慧型手機智慧型手機
智慧型手機
 
Utagoe intro
Utagoe introUtagoe intro
Utagoe intro
 
OSC2009KYOTO Asterisk User\'s Group Japan
OSC2009KYOTO Asterisk User\'s Group JapanOSC2009KYOTO Asterisk User\'s Group Japan
OSC2009KYOTO Asterisk User\'s Group Japan
 
Cloud for Enterprise IT (Japanese)
Cloud for Enterprise IT (Japanese)Cloud for Enterprise IT (Japanese)
Cloud for Enterprise IT (Japanese)
 
Web技術勉強会10回目(Slideshare用)
Web技術勉強会10回目(Slideshare用)Web技術勉強会10回目(Slideshare用)
Web技術勉強会10回目(Slideshare用)
 
2009/04/19 UI Gathering專題演講-UI prototype實作經驗分享
2009/04/19 UI Gathering專題演講-UI prototype實作經驗分享2009/04/19 UI Gathering專題演講-UI prototype實作經驗分享
2009/04/19 UI Gathering專題演講-UI prototype實作經驗分享
 
Spring Dynamic Modules
Spring Dynamic ModulesSpring Dynamic Modules
Spring Dynamic Modules
 

Android JNI

  • 1. Android Hackathon 2009.3.20 Android で JNI 餃子のまち 宇都宮 村沢 邦夫
  • 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. 準備 • Android のソースを取得してビルド – 手順は次の URL に詳しく書いてあります – http://source.android.com/download – 実行環境に合わせてブランチを選んでね • 2009.3.14頃の master で試してます • ビルドされたモノは /xxx/out に出来る – /xxx は Android ソースを置いたディレクトリ – /xxx は自分の環境に合わせて直してね
  • 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. ライブラリ • Android 用ライブラリ • 必要に応じてライブラリパスに設定 – /xxx/out/target/product/generic/obj/lib
  • 6. ヘッダファイル • Android 用ヘッダファイル • 必要に応じてインクルードパスに設定 – /xxx/bionic/libc/include – /xxx/bionic/libc/kernel/arch-arm – /xxx/libc/arch-arm/include – /xxx/kernel/include
  • 7. JNI • Android 用 JNI ヘッダファイル • インクルードパスに設定 – /xxx/dalvik/libnativehelper/include/nativehelper
  • 8. その他(1) • リンカスクリプト(shared library 用) – /xxx/build/core/armelf.xsc • Dynamic Linker / Loader – /system/bin/linker • Android のライブラリ置き場 (LD_LIBRARY_PATH) – /system/lib
  • 9. その他(2) • agcc – http://plausible.org/andy/agcc – コンパイル用スクリプト – ライブラリ、インクルードパス等を自動で設 定してくれるので便利 – 以降、コンパイルは agcc を使って説明
  • 10. JNI 作成手順 ① Java コード作成 ② クラスファイル生成 ③ C / C++ 用ヘッダファイル生成 ④ C / C++ コード作成 ⑤ 共有ライブラリ生成
  • 11. JNI で Hello World • HelloWorld クラスを作成 – パッケージ名 jni_test.helloWorldJNI • ネイティブメソッドとして get を用意 – 「Hello JNI World」の文字列を返す • ネイティブライブラリは libHelloWorld.so とする – ソースは HelloWorld.c • Activity は HelloWorldJNI とし HelloWorld クラス の get メソッドで文字列を取得し表示
  • 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. ② クラスファイル生成 HelloWorld.class • Eclipse でコンパイルすればOK • コマンドラインでやるなら $ javac jni_test/helloWorldJNI/HelloWorld.java
  • 14. ③ C / C++ 用ヘッダファイル生成 jni_test_helloWorldJNI_HelloWorld.h • javah コマンドで生成 – クラスファイルからヘッダファイルを生成 – jni_test_helloWorldJNI_HelloWorld.h – C / C++ コードでインクルード • Eclipse からやる方法は知らない(汗) $ javah jni_test.helloWorldJNI.HelloWorld
  • 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. ④ 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. ⑤ 共有ライブラリ生成 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. 共有ライブラリを転送 • 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. 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); } }