Android版での注意点
Android NDKを利用して,spComponentを用いて開発したGUIアプリケーションを
Androidで動作させることができます.基本的に,すでにspComponentを用いて
開発済みのアプリケーションのソースコードをそのままで動かすという感じではなく,
ソースコードをAndroid用に改変して動かすことを想定しています.
ソースコードの互換性はある程度高いと思いますが,細かい挙動が結構異なります
(詳細は下記の制約の項を見て下さい).
以下では,サンプルプログラムのビルド方法と,サンプルプログラムをベースに
新しいプロジェクトを作成する方法を説明しています.
Androidでの開発に精通している人は,サンプルプログラムを用いる必要は
ありません.その際には,コンパイル時に,#define ANDROIDを行う必要があります.
あるいは,サンプルプログラムのように,-DANDROIDオプションをjni/Android.mkの
LOCAL_CFLAGSに追加します.
Android SDKとAndroid NDKが正しくインストールされていることが必要です.まずは,
Googleの提供するNDKのサンプルプログラムがndk-buildによりビルドでき,
プログラムが正しく動作することを確認して下さい.また,サンプルプログラムは
eclipseを用いて動作チェックを行っていますので,eclipseを使用することを
お勧めします.
このライブラリを使用するには,拙作のspBaseとspComponentの2つのライブラリが
別途必要になります.サンプルをそのままビルドするには,以下のようなディレクトリ
構成である必要があります.なお,OpengGLを用いる場合には,さらにspComponentEx
ライブラリも必要となります.OpenGLを用いない場合には,下記の spComponentEx
の記述の部分は不要です.
[ディレクトリ構成パターン1]
include/
sp/*.h (spBase,spComponent,spComponentEx の全てのヘッダファイル)
spBase/
android/
spComponent/ (このREADMEファイルがあるディレクトリ)
android/
example/
android/
[ディレクトリ構成パターン2]
spBase/
sp/
android/
../ (このREADMEファイルがあるディレクトリ)
android/
example/
android/
spComponent/
sp/
example/
spComponentEx/ (OpenGLを使用する場合)
sp/
上記の「../」ディレクトリは,配布形態によっては [ディレクトリ構成パターン1] と
同様にspComponentディレクトリと統合されている場合があります.
spComponentに依存した不都合はそれほどないと思いますが,Androidの開発環境自体
が正常にインストールするために苦労することが多いですので,Androidの開発経験に
乏しい人はご注意下さい(例えば,インストール状態によってはndk-buildがまともに
動作しないとか,Android SDKのいくつかのバージョンではデフォルトでインストール
されるProgurardがまともに機能しないなど).
example/android にeclipseとAndroid Studio両用のサンプルプロジェクトがあります.
通常のAndroidのNDKを用いたプロジェクトのビルド方法とほぼ同様にビルドできます.
なお,サンプルのビルドには,予めspBase(spBase/android)と
spComponent(spComponent/android)のスタティックライブラリ,そしてspComponent
のexampleのソースコードが必要です.具体的には,この内容と同じREADMEファイルのあるディレクトリから
見て,以下のファイル・ディレクトリが用意されている必要があります.
android/obj/local/armeabi/libspc.a
../spBase/android/obj/local/armeabi/libspb.a
../spComponent/example (spComponentのexampleのソースコードがあるディレクトリ)
eclipseとAndroid Studioのそれぞれのビルドまでの手順は,以下の通りです.
- 「File」メニューから「Import...」を選択して以下の手順でサンプルプロジェクトを
インポートします(ここでは特にAndroidに依存した手順はありません).
- ダイアログを開いた後,「Existing Projects into Workspace」を選択し「Next」をクリック.
- 「Select root directory」で特定のサンプルのあるディレクトリを指定
- 「Projects」のリストの欄にプロジェクト名が表示されており,
かつチェックが入っていることを確認の上「Finish」ボタンを押し,
サンプルプロジェクトをインポート
- コマンド上で,サンプルプロジェクトのあるディレクトリ(1.で指定した
ディレクリ)に移動した後,ndk-buildを実行します.再ビルドしたい場合は,
-Bオプションを付けると良いでしょう.
ndk-build -B
arm以外のアーキテクチャ用のビルドも行いたい場合は,下記のように APP_ABI=all
オプションを付けます.
ndk-build -B APP_ABI=all
NDKの制約で,再ビルド時にエラーが発生することもありますが,その場合は
binディレクトリの中身とobjディレクトリの中身を全部消去してからやり直すと
うまくいくことが多いようです.
- パッケージ・エクスプローラから,読み込んだサンプルプロジェクトを右クリック
してリフレッシュし,実行して下さい.
- 「File」メニューから「New」>「Import Project...」を選択してサンプルプロジェクトを
選択してインポートします.正確には,Android Studio専用のプロジェクトではなく,
gradleのプロジェクトとして読み込むことになります.
- 上記のeclipseの場合と同様にndk-buildを実行します.まだAndroid StudioのNDK
に関する仕様が固まっていない気がすることもあり,Android Studioで直接ビルド
できるようにはしていません.
- 「Run」メニューから「Run '****'」を選択し,実行します.
example/android/template ディレクトリが,サンプルプログラムをビルドする
ためのテンプレートとなっています.このディレクトリを別名でコピーし,
以下の箇所を修正すると,eclipse・Android Studio用の新しいサンプルプロジェクトを作成できます.
- 「.project」ファイルの3行目のtemplateの部分を新しいサンプルの名前に変更
(eclipse用)
- 「AndroidManifest.xml」ファイルの3行目のtemplateの部分を
新しいサンプルの名前に変更
- 「build.xml」ファイルの2行目のtemplateの部分を新しいサンプルの名前に変更
(eclipse用)
- 「build.gradle」ファイルの27行目のtemplateの部分を新しいサンプルの名前に変更
(Android Studio用)
- 「res/values/strings.xml」ファイルの3行目のtemplateの部分を
新しいサンプルの名前に変更
- 「jni/Android.mk」の11行目のtemplateの部分を新しいサンプルの名前に変更
- 「jni/Android.mk」の12行目のtemplate.cの部分を新しいサンプルの
ソースファイル名に変更(例:test.c).このテンプレートでは,下記のように
実際のソースファイルを #include を使って読み込んでいます.
#include "../../../../../spComponent/example/track_bar.c"
- 7. で変更したソースファイルの中身のtrack_bar.cの部分を実際に存在する
サンプルのソースファイルに変更
- これらの処理が全て終わった後,上の「サンプルのビルド」と同じ手順でビルド
して下さい.
- eclipse・Android StudioやAndroid SDKのバージョン等によっては,ソースコードや全ての設定
ファイルに異常がなくてもビルドに失敗したり,アプリケーションが立ち上がらない
ことがあります.まずは,以下の手順を試して下さい.
- プロジェクトの右クリックメニューからプロパティを選択し,ダイアログを開く
- ダイアログの「Libraries」タブを選び,spcomponent.jar と
Android 2.3.3 を残し,それ以外を消去
- 「Order and Export」のタブで spcomponent.jar にチェックを入れて一番上に持ってくる
それでもうまくいかない場合(あるいは上の手順を実行できる状況になっていない
場合)は,同様の問題が発生した場合の,Androidアプリケーションに固有の問題
の解決方法がWeb上の検索で大量に出てきますので(Proguardのバージョンを
上げるとか,cleanをし直す必要があるとか,一度ライブラリを削除してから
再登録するとか),それらを根気良く試すしかないと思います.
原因はAndroidの開発環境自体に起因するものです.私もspComponentとは無関係に
これらの現象に遭遇していますが,予期できないタイミングで発生することが
多いです.
- スレッドを利用したアプリケーションの場合は,端末を回転しても終了しない設定
にして下さい.この設定を有効にしない場合,異常終了します.
設定は,通常のAndroidアプリケーションと同様,AndroidManifest.xmlの
<activity から > の間のどこかに,「android:configChanges="orientation|screenSize|keyboardHidden"」
を追加します.
- スレッドからGUI関連の関数を直接呼び出すと(example/thread.cなど)
アプリケーションが異常終了します.スレッドからGUI関連の関数を呼び出したい
場合は,example/thread_event.cのように,ユーザーイベントを用いて間接的に
呼び出すようにして下さい.
- メニューにおいて,サブメニューは機能しません.Android自体の制約です.
実際には,Android端末のほとんどは小型端末のため,深い階層のメニューはかなり
使いづらいと思いますので,大きな制約ではないと考えています.
- 通常のC言語でexitを呼び出した場合などと異なり,spQuitを呼び出して
アプリケーションを終了した後は,その後も処理が続けられます.ですので,
spQuitの直後に処理は書かないで下さい.spComponentの関数を呼び出すと
異常終了します.Androidでは,exit関数の呼び出しは推奨されないためです.
- グローバル変数・スタティック変数の値は,アプリケーションが終了しても保持される
ことがあります.基本的には,spMain関数などで初期化をするようにして下さい.
- spDispatchEvent関数(example/loop_test.cなどで使用)は動作しません.
- モーダルウィンドウに付属しているボタン(OKボタン・キャンセルボタンなど)は,
他の環境とは異なり,クリックするとウィンドウを閉じる仕様になっています.
ただし,モーダルウィンドウの場合はウィンドウを閉じる関数が何もしない
仕様になっているため,他の環境とソースコードを共有することは可能です.
- モーダルウィンドウを用いる場合(ウィンドウポップアップ後に
ウィンドウポップダウンまで返ってこない関数を用いる場合),それが開いている
間に別のモーダルウィンドウを開くことはできません.
アプリケーションが固まります.Androidの制約もあり,対処ができませんでした.
同じ理由で,モーダルウィンドウが開いている間はモーダルウィンドウ以外の
GUIを制御する関数を呼び出すことはできません.モーダルウィンドウ内のGUI
パーツは制御可能です.
- ホームボタンや戻るボタンを押した場合には,アプリケーションが終了するように
してあります.これは,終了しないようにした場合,スレッドアプリケーションに
おいて再開後にアプリケーションが正常に機能しなくなるためです.
Last modified: "2016-04-10 12:43:32 hideki"