Eclipse 上で Android NDK プロジェクトを作成する方法

# はじめに

Eclipse 上で、Android NDK プロジェクトを作成する方法を説明します。

ネット上に同じような記事がいくつもありますが、筆者の環境では設定方法に多少の違いがあったため、改めて書いてみました。


# 開発環境

* Mac OSX : 10.9.5
* Java SE Development Kit : 1.7.0_51

* Android SDK : 24.0.2
* Android NDK : r10d

* Eclipse : 4.4.1
* Android Development Tools (Eclipse plugin) : 23.0.4.1468518
* Android Native Development Tools (Eclipse plugin) : 23.0.4.1468518


# 実行環境

* Nexus 7 (2013)
* Android 4.4.4


# 今回作成したプロジェクト

今回作成した Android NDK プロジェクトを Github に置きました。

[Github - sample-android-ndk-eclipse](https://github.com/cotrpepe/sample-android-ndk-eclipse)

# Android NDK とは？

Android NDK とは、C や C++ で Android アプリを開発するためのツールセットです。詳細は、以下の公式サイトを参照してください。

[参考）Android NDK（英語）](
https://developer.android.com/tools/sdk/ndk/index.html)


# 各種ツールのインストール

Eclipse 上で Android NDK プロジェクトを作成するためには、以下のツールをインストールする必要があります。

* Java SE Development Kit
* Android SDK
* Android NDK
* Eclipse
* Android Development Tools (Eclipse plugin)
* Android Native Development Tools (Eclipse plugin)

ツールのインストール方法については、以下のサイトなどを参照してください。

[参考）Android SDK/NDK インストール手順](http://dench.flatlib.jp/opengl/androidsdk)

[参考）Androidアプリケーション開発環境の構築](http://note.chiebukuro.yahoo.co.jp/detail/n98762)

[参考）Android NDKを使った開発環境の構築](http://note.chiebukuro.yahoo.co.jp/detail/n136598)


# Android Application Project の新規作成

手順１）Eclipse を起動します。

手順２）File -> New -> Other... を選択します。

![1.png](https://qiita-image-store.s3.amazonaws.com/0/46434/4aac02b5-373d-2ac7-7d00-0be0bb2296bb.png)


手順３）Android Application Project を選択し、Next をクリックします。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/46434/68e48fae-1ee5-24da-a93b-db2ddd5d170f.png)


手順４）Application Name を記入し（ここでは、HelloNDK としました）、Next をクリックします。

![3.png](https://qiita-image-store.s3.amazonaws.com/0/46434/6a2b2418-2b25-5f0b-2494-e50648e0f4a2.png)


手順５）Next をクリックします。

![4.png](https://qiita-image-store.s3.amazonaws.com/0/46434/c482aa13-1f77-70cd-2af0-cf6649f5af98.png)


手順６）Next をクリックします。

![5.png](https://qiita-image-store.s3.amazonaws.com/0/46434/9e9d4ba0-de2e-ce97-62cb-9e3e5ed333d3.png)


手順７）Next をクリックします。

![6.png](https://qiita-image-store.s3.amazonaws.com/0/46434/262fb2fe-b979-fcc2-62cc-2def25263567.png)


手順８）Finish をクリックします。

![7.png](https://qiita-image-store.s3.amazonaws.com/0/46434/8cc93fed-3a4b-f347-d3fc-664386338b39.png)


# Native Support の追加

手順９）プロジェクト名（HelloNDK）を右クリックします。

![8.png](https://qiita-image-store.s3.amazonaws.com/0/46434/111f7216-ed11-5ff7-2e4f-d7dbaef6ce16.png)


手順１０）Android Tools -> Add Native Support... をクリックします。

![9.png](https://qiita-image-store.s3.amazonaws.com/0/46434/1bb75aec-4f63-0625-9785-7f545880d2f1.png)


手順１１）ライブラリ（.so ファイル）の名前を指定して、Finish をクリックします。ここでは、デフォルトのままとしました。

![10.png](https://qiita-image-store.s3.amazonaws.com/0/46434/043c3178-e3fb-2f7b-5550-af3d677a70d6.png)


手順１２）jni ディレクトリが作成され、中に HelloNDK.cpp と Android.mk が作成されます。

![11.png](https://qiita-image-store.s3.amazonaws.com/0/46434/e6000766-588c-abe4-e29f-0333a18fc37d.png)


# コードの追加

手順１３）res -> layout -> acvitiy_main.xml に、以下の赤枠部分のコードを追加します。

![12.png](https://qiita-image-store.s3.amazonaws.com/0/46434/8d3c8d5f-f077-e13b-5519-c8d9a12895d6.png)

---

補足）
```android:id="@+id/textView"``` は、TextView に id を付与するためのコードです。

---

手順１４）src -> com.example.hellondk -> MainActivity.java に、以下の赤枠部分のコードを追加します。

![13.png](https://qiita-image-store.s3.amazonaws.com/0/46434/38076430-b0a7-ba35-d9b7-f493c801eb99.png)

---

補足）
以下は、手順１１で指定した .so ファイルを読み込むためのコードです。

```java
static {
	System.loadLibrary("HelloNDK");
}
```

以下では、native メソッドを宣言しています。

```java
public native String getMsgFromNDK();
```

以下のコードで、TextView に geMsgFromNDK() メソッドの戻り値を設定しています。

```java
TextView text = (TextView) findViewById(R.id.textView);
text.setText(getMsgFromNDK());
```

---



# javah コマンドの実行

---

### 補足） javah コマンドとは？

javah コマンドとは、java のクラスファイルから、C/C++ とのインターフェースに必要なヘッダファイルを自動的に生成するためのツールです。

---

手順１５）エディタ上で MainActivity.java をクリックし、アクティブ状態にします。

![14.png](https://qiita-image-store.s3.amazonaws.com/0/46434/7d2c0aa0-7c93-97dc-c8ee-8b843d1b7dd7.png)


手順１６）Run -> External Tools -> External Tools Configurations... を選択します

![15.png](https://qiita-image-store.s3.amazonaws.com/0/46434/cea00297-7396-dbb7-f395-015578599df1.png)


手順１７）Program を選択します。

![16.png](https://qiita-image-store.s3.amazonaws.com/0/46434/ef68eb61-db8a-3ab1-93e6-007408bf42b4.png)


手順１８）New launch configuration をクリックします。

![17.png](https://qiita-image-store.s3.amazonaws.com/0/46434/01734def-ade1-7dbd-6b43-e3dc39dc1122.png)


手順１９）以下の赤枠部分を記入します。

![18.png](https://qiita-image-store.s3.amazonaws.com/0/46434/92b669f4-174d-3c52-ea06-5e366f2cd18f.png)


|項目      |内容                  |
|:--------|:---------------------|
|Name     |自由に決めてかまいません  | 
|Location | ${system_path:javah} |
|Working directory | ${project_loc}|
|Arguments |-d jni -classpath bin/classes:/Users/XXX/Library/Android/sdk/platforms/android-21:/Users/XXX/Library/Android/sdk/extras/android/support/v7/appcompat/libs/android-support-v7-appcompat.jar:/Users/XXX/Library/Android/sdk/extras/android/support/v4/android-support-v4.jar:/Users/XXX/Library/Android/sdk/platforms/android-21/data/layoutlib.jar ${java_type_name}

---

### 補足） Arguments の -classpath オプションについて

Arguments の -classpath オプションについては、以下の点で筆者の環境と他のサイトで違いがありました。

その１）
パスの区切りについては、セミコロン（;）ではなく、コロン（:）にする必要がありました。

その２）
また、以下の４つのパスを指定する必要がありました。

* /Users/XXX/Library/Android/sdk/platforms/android-21
* /Users/XXX/Library/Android/sdk/extras/android/support/v7/appcompat/libs/android-support-v7-appcompat.jar
* /Users/XXX/Library/Android/sdk/extras/android/support/v4/android-support-v4.jar
* /Users/XXX/Library/Android/sdk/platforms/android-21/data/layoutlib.jar

---

手順２０）Run をクリックします。

![19.png](https://qiita-image-store.s3.amazonaws.com/0/46434/96ac6d67-ff6a-88f5-653b-2d56da5ad880.png)

これで、jni ディレクトリに com_example_hellondk_MainActivity.h というヘッダファイルが作成されます（ただし、Eclipse の画面を更新しないと、このファイルを見ることができません。以下の手順で画面の更新を行います）。

手順２１）jni ディレクトリを選択し、F5 キーを押します。

![20.png](https://qiita-image-store.s3.amazonaws.com/0/46434/deacf290-9f46-e9bd-1664-6432e2ad5c8c.png)


手順２２）com_example_hellondk_MainActivity.h が作成されていることが確認できます。

![21.png](https://qiita-image-store.s3.amazonaws.com/0/46434/61abe260-1c00-91dd-1a05-3d00439a532a.png)


# コードの追加

手順２３）com_example_hellondk_MainActivity.h に、MainActivity.java で宣言した、messageFromNDK 関数のプロトタイプ宣言があります。後ほど使うので、これをコピーしておきます。

![22.png](https://qiita-image-store.s3.amazonaws.com/0/46434/a259311a-c5a9-2b67-c0aa-f29600fa7108.png)


手順２４）jni ディレクトリにある、HelloNDK.cpp に、以下の赤枠部分のコードを追加します。

補足）
手順２３でコピーしたものをペーストして使うと楽です。コピペした場合は、引数名を追加することを忘れないで下さい（JNIEnv *env と、jobject thisz）。

![23.png](https://qiita-image-store.s3.amazonaws.com/0/46434/6f6f9ca6-53e8-1c86-51dc-db14d789e720.png)

補足）
以下で、先ほど作成した、com_example_hellondk_MainActivity.h をインクルードしています。

```cpp
#include <com_example_hellondk_MainActivity.h>
```

以下のコードで、getMsgFromNDK メソッドを作成しています。関数名は、「Java_パッケージ名_関数名」で指定する決まりになっています。

```cpp
JNIEXPORT jstring JNICALL Java_com_example_hellondk_MainActivity_getMsgFromNDK(JNIEnv *env, jobject thisz) {
	jstring jstr = env->NewStringUTF("Hello from NDK!");
	return jstr;
}
```


# 実行

手順２５）HelloNDK をクリックしてアクティブ化し、以下の赤矢印が指している、小さな黒い三角形をクリックします。

![24.png](https://qiita-image-store.s3.amazonaws.com/0/46434/d805c9f9-b918-9ff6-52d3-7017889947cc.png)


手順２６）Android Application をクリックし、実行します。

![25.png](https://qiita-image-store.s3.amazonaws.com/0/46434/289a6998-77bc-083e-293b-87e89806cd84.png)


手順２７）Android 端末上で、以下のように表示されれば成功です。

![26.png](https://qiita-image-store.s3.amazonaws.com/0/46434/aa62595d-99b0-8cfc-af7e-584fca61a81a.png)

補足１）
筆者は、実機上（Nexus 7, Android 4.4.4）で動作確認を行いました。

補足２）
エミュレータや実機での動作確認の詳細については、他のサイトを参照してください。