スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[Android] JNI(Java Native Interface)を使ったサンプル

お久しぶりの更新です(・ω・)
今回はAndroidでJNI(java native interface)を使う方法について。

AndroidアプリがDalvikVM上で動くというのはご周知のとおりですが、
DalvikVMはバイトコードインタプリタ方式の為、C言語等で作成された
ネイティブコードなんかと比べて格段に遅いらしいです。
そこでネイティブコード(C++で作成)をAndroidアプリで実行する方法を試しにやってみました。

※以下の内容はEclipseでAndroidアプリの開発をした事があるのを前提としている為、
Androidアプリの作り方等、初歩的な部分はすっ飛ばしますのでご了承ください。


【調理環境】
OS: WindowsXP(SP3)
IDE: Eclipse(Pleiades 3.6) Android SDKのバージョンはr10を使用。
Android: X06HT(HTC Desire) 実機デバッグ用と化しているような


【前準備】
・Android NDKの入手
ここからダウソ。
今回は「android-ndk-r6-windows.zip」をダウソしました。

・Cygwinのダウンロード
Android NDKを使うにはCygwinが必要です。
ここから「setup.exe」をダウンロードし、セットアップを実行します(結構時間かかります)。
インスコ方法はこちらに秀逸な記事があるので参照してください。

今回Cygwinでダウソしたパッケージは、Develカテゴリの以下2つ。
gcc-core: C compiler
make: The GNU version of the 'make' utility


通常、Cygwinのセットアップを実行するとCドラの直下にcygwinフォルダが作られるので、
cygwinフォルダに先ほど入手したAndroid NDKを解凍して放り込みます。


【JNIプロジェクトの作成】
まず手始めにEclipseで通常のAndroidプロジェクトを作成します。
今回作成したプロジェクトは以下のような感じ。
jni01.png

プロジェクトが生成されたら、Activityクラスを編集して以下のようなコードにします。

public class TestJniActivity extends Activity
{
static
{
// JNIライブラリのロード
System.loadLibrary("TestJni");
}

// JNIメソッドの定義
public native String getTestJniNative();

@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// JNIメソッドをコールし、textViewに値を表示
TextView textView = (TextView)findViewById(R.id.textView);
textView.setText(getTestJniNative());
}
}

ここでのポイントは
・JNIライブラリ名: TestJni
・JNIメソッド名: getTestJniNative
という点。

プロジェクトをビルドすると、プロジェクトフォルダのbin以下に
コンパイルされた「TestJniActivity.class」が生成されているので、
このclassファイルからJavaのjavahコマンドでヘッダファイルを生成します。オプションの-dはお好みで。

>javah -classpath C:\~\bin [-d folder_name] com.taepon.TestJniActivity

上記を実行するとcom_taepon_TestJniActivity.hというファイルが生成されます。


#include
#ifndef _Included_com_taepon_TestJniActivity
#define _Included_com_taepon_TestJniActivity
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jstring JNICALL Java_com_taepon_TestJniActivity_getTestJniNative
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif

次にTestJniActivityでコールしたgetTestJniNativeメソッドをネイティブコードで記述します。
ネイティブコードは先ほど作成したヘッダファイルを元に行います。
ファイル名はcom_taepon_TestJniActivity.cとしました。

#include "com_taepon_TestJniActivity.h"

JNIEXPORT jstring JNICALL Java_com_taepon_TestJniActivity_getTestJniNative
( JNIEnv *env, jobject obj )
{
return (*env)->NewStringUTF(env, (char *)"hogehoge");
}

ここでのポイントは
・#includeに先ほど生成したヘッダファイルを指定
・JNIEXPORT~はヘッダファイルと同じにする(引数が若干違う)


この生成した2つのファイルから共有ライブラリ(.soファイル)を生成します。
まず、Android NDKフォルダに「apps」フォルダを生成し、
以下の構成でファイルを生成&配置します。

[cygwin/Android NDKフォルダ]
└ apps(+)
  └ TestJni(+)
    ├ Application.mk(後述)
    └ jni(+)
      ├ Android.mk(後述)
      ├ com_taepon_TestJniActivity.h
      └ com_taepon_TestJniActivity.c

Application.mk

APP_PROJECT_PATH := $(call my-dir)
APP_MODULES := TestJni

ここでのポイントは
・APP_MODULES := TestJni

Android.mk
Android.mkの内容についてはこちらの秀逸な記事を参照。

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := TestJni
LOCAL_SRC_FILES := com_taepon_TestJniActivity.c
LOCAL_LDLIBS := -llog
LOCAL_ARM_MODE := arm
LOCAL_PRELINK_MODULE := false

include $(BUILD_SHARED_LIBRARY)

ここでのポイントは
・LOCAL_MODULE := TestJni
・LOCAL_SRC_FILES := com_taepon_TestJniActivity.c

CygwinコンソールでAndroid NDKのフォルダに移動し、makeコマンドを実行。
make APP=TestJni -B
jni02.png
実行すると、Android NDKフォルダのapps/TestJni/libs/armeabi以下にlibTestJni.soが出来ます。

この生成されたlibTestJni.soをEclipseのAndroidプロジェクトに突っ込みます。
(libsフォルダを生成し、そこにarmeabiフォルダごと突っ込む)
jni03.png

その後、Androidプロジェクトを実行し、Activity(画面)にネイティブメソッドから返されたhogehogeが表示されればおk。
関連記事
スポンサーサイト

Pagination

Trackback

Trackback URL

http://morado106.blog106.fc2.com/tb.php/80-bf5f4076

Comment

Post Your Comment

コメント登録フォーム
公開設定

Utility

プロフィール

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。