Androidの開発を決断したまでは良かったのですが・・・。
Androidの開発環境を整えるまでにかなり苦労したのでその日記です。
ほかの記事にはないような項目がありますのでつまずいている人は見てみると良いかもしれません。
まずはJava Development Kitのインストールが・・・
つまずいてはいませんが、ある意味つまずいた項目です。というのも、JDKとJREの対象となるCPU Architectureが違う意味で複雑だったからです。
x86版のOSを使っているならものすごい簡単で、単に
- (必要であれば)旧のJREをいったんアンインストール
- JDKをインストール(JDK7でも開発は出来るが、時々はまるらしい)
ですむのですが、x64版のOSを使っているとちょっとしたはまりがあって、
- x64版なのでJDKもx64版を使うのが良いと思われる
- が、Eclipseもx64版とx86版があり、日本語化パッケージのPleiadesがデフォルトで公開しているAllInOneパッケージはx86版のみ
- ということは、出来る限りx64版とx86版のランタイムを合わせるか、x86版のJDKのみを入れてx64版を無視する必要がある
ということを考える必要が出てきます。
私の場合は、x86版がJRE7、x64版がJDK7をインストールしています。(旧で入っていたJRE6(x86)はアンインストールしてきれいにしました)
というわけで、Eclipse(Pleiades)はx86版を使用して起動するようにしています。
Eclipseはパス長が短いところで展開するように
WindowsにはMAX_PATHという定義があり、これが260に設定されています。
総パス名がこれより長くなるといろいろなWindowsプログラムでエラーが出るようになるのですが、Eclipse(というかJava)はどうもかなりパス名が長くなる傾向があるようで、
いろいろなサイトでパス名を短くなるように、ということが書いてあります。気をつけましょう。
Android SDKの最新版がちょうど今日公開だった・・・
おかげでWebからパッケージを持ってくるという作業がEclipseで何回も失敗するという羽目に・・・。
仕方がないので、必要なzipファイルをすべてダウンロード(android-sdk_r18-windows.zip,android-ndk-r7c-windows.zip,ADT-18.0.0.zip)して、それをローカルで読み込ませるという作戦に出ざるを得なくなりました。
ADTのパッケージをEclipseに読み込ませて、AndroidのSDK Managerを設定して、パッケージをダウンロードして・・・を頑張っていました。
アクセスが集中しているのでパッケージのダウンロードが遅いこと・・・。
Android NDKの設定が予想以上にやっかい
必要なのはCygwinなので、セットアップを行って環境を整える必要があります。開発ツールであるmakeやgcc、付属するライブラリを忘れずに手に入れましょう。
そしてテストでプロジェクトを作ってNDKを作るためのヘッダを作成するためにjavahを起動したら・・・。
エラー続発・・・!
いろいろなサイトを見回ってやり方を見てみましたがどうもうまくいかない。ということで、どうにかしました。
ちょっとサンプルを書いてみます。
1.Eclipseのワークスペースに「ndktest」を作成
普通のAndroidプロジェクトとして作成されますので。パッケージ名は「sample.ndktest」を使います。
このとき、アクティビティを「NDKTestActivity」として作ってみます。
2.JNIを参照するようにコードを修正
対象はNDKTestActivity.javaです。
package sample.ndktest; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class NDKTestActivity extends Activity { static { System.loadLibrary("ndktest"); } native private String ndktext(); /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView view = new TextView(this); view.setText(ndktext()); setContentView(view); } }
いろいろなところで書かれているサンプルコードがほぼそのままになっています。
注意が必要なのは
static { System.loadLibrary("ndktest"); }
でロードするライブラリ名がこの後出てくるというところですね。
3.JNIのヘッダを作成
私の場合、javahでパッケージ検索がうまくいかなかったので手動でやりました。
特にjavahの実行時エラーとして
エラー: android.app.Activityにアクセスできません
android.app.Activityのクラス・ファイルが見つかりません
といったように、Androidのパッケージにアクセスできなかったパターンでこのようにすると良い、というものです。
あらかじめ、対象プロジェクトに「jni」というディレクトリを作成しておきます。また、JDKの実行ファイルパスにはパスが通っている(環境変数中のPATHにJDK実行ファイルのパスが設定してある)ものとします。
AndroidSDKをインストールしたディレクトリを「C:\hoge\android-sdk」とします。このとき、ワークスペースの対象プロジェクトのコマンドプロンプト(Cygwin,cmd(Windows付属)どちらでも可)で、
C:\workspace\ndktest>javah -classpath "bin/classes;C:\hoge\android-sdk\platforms\android-10\data\layoutlib.jar;C:\hoge\android-sdk\platforms\android-10\data" -d jni sample.ndktest.NDKTestActivity
と入力します。
ちなみに、この中に出てくる「android-10」は、Androidプロジェクトを作ったときのターゲットAPIのバージョン番号です。(2.3.3を指定して作成したときは10になる。プロジェクト作成時のターゲットバージョンに合わせて変更すること)
このパスはいろいろなところを見ると、環境変数のCLASSPATHを参照しているらしいですが、その記述がないとか、Androidのパッケージを複数セットしてあるので・・・というパターンでこういう指定が必要になるようです。
作成に成功するとjniの中に「sample_ndktest_NDKTestActivity.h」が作成されます。
4.CファイルおよびAndroid.mkを作成
両者ともjniのディレクトリに書き込みます。どうせなのでCファイルは同名で「sample_ndktest_NDKTestActivity.c」としておきます。
[sample_ndktest_NDKTestActivity.c]
#include "sample_ndktest_NDKTestActivity.h" /* * Class: sample_ndktest_NDKTestActivity * Method: ndktext * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_sample_ndktest_NDKTestActivity_ndktext(JNIEnv *env, jobject thiz) { return env->NewStringUTF("Hello, World from C."); }
[Android.mk]
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := nkdtest LOCAL_SRC_FILES := sample_ndktest_NDKTestActivity.c include $(BUILD_SHARED_LIBRARY)
ちょっとしたみそはLOCAL_MODULEの指定をこの段階でSystem.loadLibraryで指定した名前に変更してしまうことです。
これをやるとApplication.mkが使えなくなるのですが、私の場合は使う必要がないと判定して無視しました。
5.libnkdtest.soを生成
ndk-buildの出番です。この生成はCygwinのターミナル上で行う必要があります。
完了すればlib/armeabiにlibnkdtest.soが生成されているはずです。
これでやっとNDKを使ったAndroidアプリのテストが出来るわけですね・・・。
なんか環境変数依存が多すぎない?
環境を整えていくうちに思ったことです。
結局、今回かなりの数の環境変数が増えてしまいました。具体的には
- ANDROID_HOME,ANDROID_SDK_HOME (AVDの作成場所に影響)
- ANDROID_NDK_ROOT (Android NDKのルートパス設定。Cygwinの中だけで問題ないのが救い)
- CLASSPATH (javahなどで参照される各種クラスファイルがあるパス)
- Path (Javaの実行ファイルのパスとか、Androidの各種ツールの実行ファイルのパスとかが追加され・・・)
を変更しましたし、それ以外にも変更が必要なことがあるようです。
さすがに初心者にはちょっと手を出しづらいのではないでしょうか?
何を開発するつもり?
なのでしょうか。しばらくはサンプルコードなので各種の動きを見ていく予定です。