tyosyoshinsy

初心者の為の Android NDKを使用したプログラム例

公開日:2020/4/19

Android 用のアプリ開発をするための準備は、 Android Studio入門 で紹介した方法を、一通りやっていただければ、基本的な準備は完了なので、次はさっそくプログラミングに挑戦しましょう。 このページでは、はじめのステップとして、
・空のアプリ作成
・デバッグ用の仮想マシンの準備
・空のアプリにボタンを配置
・NDKを使用した簡単な例
の順番で紹介するので、アプリ作りの流れを掴んで下さい。
特に初心者の方には、重要なポイントをピックアップしているので、最後まで参考していただけると嬉しいです。

新規プロジェクトの作成から空のアクティビティを選ぶ

 アプリケーションのタイプから、『ネイティブC++』 を選択することで、あらかじめ、 C言語を想定した、プログラム開発ができる、スケルトンを生成してくれますが、 今回は、いままで作ったアプリから、NDKを使用したアプリ開発ができるような手順を紹介したいので、あえて『空のアクティビティー』 を選択してください。

Emptyactivity

選択後は、『次へ』 を選択すると、プロジェクト名を入力して、完了です。
保存ロケーションは、自分のわかりやすいフォルダを作って準備しましょう。 この時注意していただきたいのは 日本語のフォルダ名があると後々エラー起きるので、すべてアルファベットのフォルダ名にしてください。 ※また、赤枠で囲ったチェックボックスにチェックを入れましょう。

Emptyactivity2

 プロジェクトの構成を確認する。

  プロジェクトの準備が完了したらはじめに、自動で骨格となる空のプロジェクトがビルド(生成)されます。 はじめての場合、何が出来上がったのか良く分らないと思うので簡単に解説します。
はじめは全てを理解する必要は全く無いので、以下の3点のみ、ツリーをクックしファイルを開いて確認しましょう。

Emptyactivity3

・AndroidManifest.xml
◆本アプリケーションの基本構造を定義しているものと思ってください。最初のうちは、ここをいじってプログラムする必要は ないので、こうゆうものがあるというのだけ頭に片隅の入れておいてください。

・MainActivity.java
◆アプリケーション本体である一番の母体となる出発点です。 プログラムはここからスタートしますので、 今回紹介するテストプログラムは、ここから作っていきます。

・activity_main.xml
◆アプリケーション画面のレイアウトを構成しているコード部分になります。 拡張子のとおり、レイアウトは描画は、 javaではなくxml記述になります。 ボタンや、テキスト入力などの部品は、パレットと呼ばれる、デザイナーを 使って配置する事が出来るので、はじめのうちは直接xml編集することはありません。

デバッグ用の仮想マシンの準備をしょう

スケルトンが出来上がったら、それを動かす仮想環境である、エミュレータの準備をしましょう。 Androidstudioのインストールの際に、デフォルトの環境をインストールをしたと思いますが、 信じられないほど重く遅いので、次に示す仮想環境の準備をお勧めいたします。
『Tools』 タブから、『ADV Manager』を選択して、Android Virtual Device Manager 起動させます。 ウィンドウが開きましたら、『Create Virtual Device』 を選択します。

Emptyactivity5

スマートフォン向け、タブレット向け、等の仮想マシンの種類が選べます。この選択では特に気をつける 必要はないので、好みのデバイスを選択して、NEXT を押して次に進みます。
Select a system image 画面に切り替わりましたら、Recommended(推奨)タブから、 x86Images タブ選択してください。

Emptyactivity4

現在のVerからかなり古いですが、『Nougat』のOSバージョンの、ABI x86_64の ものを選びましょう。
※ポイントとしては、64bitと(GoogleAPIs)がないものを選択します。理由としては、(GoogleAPIs)が入った 仮想マシンはサイズが滅茶苦茶大きく、かつ非常に重たく遅いため、最初の練習として使うには、ストレスが大きいのでお勧めできません。 次の項目では、特に注意する点はないので、完了を選択して、環境をダウンロードしましょう。


IntelHWXM.png

また、AndroidStudio初回起動時に、上記の『Intel Hardware Accelerated Execution』 をインストールするかの、 チェックチェックボックスがあったと思うので、インストールされているか確認しましょう。 ※インストールをしていなかったら、AndroidStudioを 一旦終了させて、 C:\User/(自分のPCユーザー名)/ のディレクトリにある、 .AndroidStudio3.* (※*はVer) と  .android のフォルダを削除しましょう。 AndroidStudio が初回起動時と同じになるので、インストールをし直しましょう。

 出来上がったスケルトンを仮想マシンで起動する

仮想マシンの準備が出来たら、動作確認を含めて、出来上がった空のアプリケーションを起動してみましょう。

Debugtest.png

Runタブから、Run'app'を選択するか、ツールバーの再生マークをクリックします。
Select Deployment Target のウィンドウが表示されたら、先ほど作成した仮想デバイス名が表示されますので 選択し、OKクリックして起動させます。(初回は、仮想マシンの立ち上がりからテストアプリの起動までかなり時間がかかりますが 気長に待ちましょう。)

定番の Hello World! まで表示されたら仮想マシンの準備と、スケルトンの準備はOKです。

Debugtest2.png
スポンサードリンク

 ボタンを使ったテストプログラムの作成

すべての準備が整ったので、仮想マシンは一旦閉じて、GUI(グラフィカルカルユーザーインターフェース、ボタンやテキスト入力等)を使用した、 テストプログラムを作ってみましょう。
activity_main.xml をひらいて、Palette からButtonとTextViewそれぞれ選択して、適当に配置しましょう。

Debugtest3.png

配置しただけだと、部品の座標関係が不明なので、このままではビルドエラーになります。 そこで、『Hello World』 テキストを基準に部品の位置関係を決めます。  決め方は下記写真を参考に、赤枠で囲った青○の部分を、ドラッグし基準先でドロップするだけで出来ます。 正常に決まると、赤丸のエラーマークが警告マークに変わり、ひとまずビルドできるようになります。
※この警告は、部品上のキャプションの(この場合だとBUTTON) テキスト文字を直接使うのは、 良くないですよという警告です。 要するに、プログラム上で記述するべきとGoogleが推奨しているのですが、 慣れるまではとりあえず無視して良いでしょう。

Debugtest4.png

 MainActivityにボタンが押された時の処理を書く

UI配置ができたので、ボタンが押された時のプログラムを書きましょう。 まずは、下記の写真を参考に、MainActivity に 赤枠で囲ったコードを記述しましょう。

TestPGM.png

内容は、ボタンが押された時に、配置したTextViewに、『はろーわーるど』 と表示するシンプルなものです。
では、記述したコードの説明をします。
・Button TestBnt; は、プログラム上で使うボタン型の変数です
・TextView TestTxt; は、プログラム上で使うテキストビュー型の変数です
次に、
・TestBnt = findViewById(R.id.button); は、デザインで配置したボタンを変数にセットします。
・TestTxt = findViewById(R.id.textView); は、デザインで配置したテキストビューを変数にセットします。
最後に、
・TestBnt.setOnClickListener( new View.OnClickListener(){
    @Overrride
    public void onClick(View v){
        Sting str = "はろーわーるど";
        TestTxt.setText(str);
    }
});
は、ボタンが押された時のイベントを記述しています。 実際は、View.OnClickListener()まで記述すると、 オーバーライド(継承)型の関数である、onClick は、自動で記述されるので、実際は、onClickで括られた 2行を記述するだけでOKです。
※黄色枠で囲った部分について
部品で張り付けた、ボタンや、テキストビューは、はじめは使うことを想定していないので、コード上で、Button や、 TextViewを記述すると警告が表示されます。 この時に、警告が出ている場所で、Alt+Enter を入力すると、 『クラスをインポートするか?』と問われるので、クリックすれば、自動で記述してくれます。
ではコードが書けたら、早速プログラムを動かしてみましょう。

TestPGM2.png

ボタンを押して、TextView が はろーわーるど に変わったらOKです。
非常に初歩的なものですが、はじめはこのプログラム作りの流れを掴んで下さい。

スポンサードリンク

 NDKを使ったプログラムを書く

最後に、NDKを使った簡単なプログラム例を紹介します。 Android NDK 向けの参考書籍が少なく、 また、インターネット上でも取り扱ってるサイトが少ないので、是非参考にしていただけたら幸いです。
はじめに、NDK のプログラムの使い方の流れを下記に示します。 C言語書かれたプログラムを、java側で そのまま使うことが出来ないので、以下の方法で、java と C/C++ が共存します。 

TestNDK.png

ここ注目してもらいたいのが、『JNI』 というキーワードで。 このJNIとは、『java Native Interface』 というもので、 JNIは、C/C++で書かれたプログラムにアクセスするための、専用の関数になります。
これは一つではなく、基本的にはJNIで定義された関数を使用して、C/C++でコーディングされたプログラムを呼び出して 実行する形になります。 では、早速その運用例を紹介します。

プログラムの書く前に準備するもの

AndroidStudioで C/C++のプログラムを書く前に準備するものがあります。それは、MakeFileと呼ばれる、 コンパイルのルールを定義するものを準備する必要があります。
ここでその詳細を説明すると非常に奥深い話になるので割愛しますが、とにかく必要で重要なポイントだけをピックアップして紹介します。
まずは、TestAPP を作ったフォルダに移動して、JNIフォルダを作って下さい。
フォルダを作る場所は、
・・・\TestAPP\app\src\main の中に
に『jini』 というフォルダを作って下さい。

TestNDK2.png

フォルダを作ったら、『Android.mk』 というファイルをメモ帳で作り、以下の内容を書いてください。

TestNDK3.png

青く選択されている、C_lib というファイルが、ライブラリとなるモジュール名になります。
LOCAL_SRC_FILES には、 C/C++ でコーディングするプログラムのファイル名を、記述します。
今後増えていく場合は、半角スペースを空けて、ファイル名を追記します。
Android.mk ファイルの準備が出来たら、同じフォルダに C_lib.cpp ファイルを作成してください。 (この段階では、C_lib.cpp 中身は空でも構いません。)
ここまでの準備ができると、AndroidStudioには、『CPP』 のフォルダが出てくると思います。

TestNDK4.png

この『CPP』 フォルダの上で、右クリックすると、Link C++ ・・ の表示が現れるので、実行します。

TestNDK5.png

ウィンドウが現れるので、 Build System のドロップダウンを、『ndk-build』 に切り替えて、 先ほど作った、Android.mk ファイルを選択します。

TestNDK6.png

リンクが完了したら、Terminal に移り、 『cd app/src/main/jni』 をうって、Jni のフォルダに移り、C/C++ の コードをビルドして、共有ライブラリを作るため、『ndk-build』 コマンドを実行します。

TestNDK7.png

※ndk-build コマンドは、Android Studio入門 のページで紹介した、『環境変数の登録』 の方法で、事前にPathを通しておく必要があります。詳しくは、Linkを参考にして下さい。

スポンサードリンク

JNI関数用のプログラムを書く

次に、C/C++で書かれたコードにアクセスするための、JNI関数を記述します。
MainActivity のあるプログラムに、とりあえず JniTest クラスファイルを作りましょう。

Jnitest.png

クラスのスケルトンが出来たら、下記写真を参考に、赤枠で囲ったコードを記述します。

Jnitest2.png

Jni関数のプロトタイプ宣言ができたので、次は実際のC/C++側の関数を定義を記述します。 C_lib.cpp を開き下記写真を参考に、全てのコードを記述してください。 

Jnitest3.png

最後に、MainActivityから、Jni関数を呼び出し、C/C++プログラムを実行させます。 下記写真を参考に、MainActivity に記述したボタンクリックイベントのところに、Jni関数を 呼び出すためのコードを記述をします。

Jnitest4.png

コードが書けたら、早速プログラムを実行してみましょう。

Jnitest5.png

ボタンを押したら、テキストビューに 『10』 と表示されたら成功です。 java側でセットした、整数5を、C/C++の コードに持っていき、C/C++の関数で更に5を加算した値が、java側に戻ってきて表示されました。
正直、これだけではなんの役にも立たない初歩のプログラムですが、これがNDKの基本になります。この仕組みは 汎用性が高く、公開されている多くの C/C++ コードを利用して多様性のあるプログラムを構築することができる 非常に強力なツールとなります。
ただ、jniの関数からは、配列などのデータ要素を、C/C++の要領でデータを取り扱うことができません。 より詳しく知りたい方は、 Android NDKプログラミングガイド にて、NDKの技法を詳しく紹介しているので是非参考にしてみてください。 ただ、一つ難点なのは、開発環境が、Eclipse なので、NDKまでの導入手順が古く、現在(2020年)では、 肝心要である導入の一番初めの部分があまり参考にならないかもしれません。 (導入までの部分は、AndroidStudioベースなので本ページをを参考にして下さい)

附録 : javah の作り方

C_lib.cpp に記述した、Jni関数は、パッケージ名、クラス名、メソッド(関数)名、だらだら書くため、 数が増えてきた場合、非常に手間がかかります。 そこて、javah というコマンドを使用して、javaクラスファイルから 関数のプロトタイプが含まれた、ヘッダファイルを作ることができます。
この、コマンドの記述が非常に分かりづらいので、こちらも参考にしていただけたら幸いです。
まず、Terminal を開き、 『javah -classpath app\build\intermediates\javac\debug\compileDebugJavaWithJavac\classes -d app/src/main/jni com.example.testapp.JniTest』 のコマンドを打ちます。

javah_.png

※上記は javah -classpath {クラスファイルのあるパス} -d {出力先ディレクトリ} {パッケージ名.アプリ名.クラス名}の要素になります。 気を付けなければいけないのが、{クラスファイルのあるパス} は、パッケージ名のフォルダまで遡るひつようがあります。 間違えると、"クラス・ファイルが見つかりませんでした。"のエラーが出ます。
例えば、クラスのあるディレクトリが、
C:\WorkFolder\TestAPP\app\build\intermediates\javac\debug\compileDebugJavaWithJavac \classes\com\example\testapp の場合、 指定先は、パッケージ名.サブパッケージ名.アプリ名まであるので
C:\WorkFolder\TestAPP\app\build\intermediates\javac\debug\compileDebugJavaWithJavac\classes を指定する必要がある。

正常にコマンドが打てると、jniフォルダにヘッダーファイルが生成されます。

javah_2.png
スポンサードリンク
© chosyoshinsya 2015~2020 All Rights Reserved.

tyosyoshinsy