2014年12月9日から、Eclipseベースの、Android Developer Tools(ADT)から、Android Studio 1.0 に切り替わった。元は IntelliJ IDEA を元にし、Android SDK やエミュレータなども自動インストールされる。現在 1.1
SDKは基本的に、Studioをインストール時に一緒にインストールされるため、特に問題はないが、NDKは別途 Android NDK のファイルをダウンロード時し、任意の場所に展開後、プロジェクト直下のlocal.propertiesに以下のように追加する。(自動インストールされたSDKの場所はここで確認もできる。)
sdk.dir=/Users/yuki/Library/Android/sdk ndk.dir=/Users/yuki/Documents/android-ndk-r10d <- 追加
AndroidStudioを起動し、プロジェクトの app フォルダ右クリックし、Open Module Settingダイアログを開き、SDK Locationタブを選択します。そこで Android SDK Location の下にある、Download Android NDKをクリックします。但しすでに ndkがダウンロードされている場合には、ndk パスだけが表示されます。
この Android Studioをベースにした開発においては、Gradleというビルドシステムが利用される(Ant、Mavenなどと同じ)。これは元はJava用に開発されたものであり、他のビルドシステムなどと違い、Groovyというスクリプト言語によって記述できる。
Gradleは、プロジェクトの直下に置かれる、build.gradleを参照しビルドが行われる。通常のコマンドでの利用では、プロジェクト直下で、gradle build と打つことで実行されるが、Android Studio 上では、build -> build project を行うことで実行できる。(ただし NDK のネイティブソースは、build だけではコンパイルされず、実行を指定して初めてコンパイルされる)
DSLとは、Domain Specific Languageの略
Android Studio 1.4以降では、プロジェクトの app を右クリックし、メニューから「Open Module Setting」を選択すると、なぜか「Project Structure」という名前(リンクとウィンドウ名が違う)のダイアログが開き、そこで gradleファイルの基本的な設定が行えます。
プロジェクトのTOPフォルダには、下記のフォルダとファイルが並びます。
フォルダ名 | 概要 |
.idea | 中にプロジェクト自体の設定情報が各種保存される。Android Studio の GUIを通じて設定するため、基本は修正の必要は無い |
app | 作成されるアプリケーションに関するすべてのファイルが保存される。内訳の詳細は下記参照 |
build | ビルドされたデータなどが保存される。直接修正するようなフォルダでは無い |
gradle | gradleのラッパー用 jar とそれらの設定が保存される。修正の必要は特になし |
ファイルの方は、比較的修正が多くなると思われる。
ファイル名 | 概要 |
build.gradle | 実際のビルドスクリプト本体。 |
gradle.properties | appとして作成する、apk を、Google Play などにアップできるように、署名をする際に修正するが、基本的には、Studio のメニュー Build > Generate Signed APK から署名すれば自動更新されるため、直接いじることは無い |
gradlew gradlew.bat | gradleコマンドのスクリプト。修正の必要なし |
local. properties | このページにもあるように、プロジェクトに関係するローカルファイルの位置をしています。 |
settings.gradle | 主にマルチプロジェクトの依存関係を設定するファイル。追加のjavaライブラリなどの指定にも利用。通常は、include ':app' だけ記述してあり、プロジェクト直下の app パッケージを組み込む指定だけにんっているが、カンマで複数指定できる。パッケージ名の前についている 「:」 はプロジェクト直下を指す。 |
appName.iml | アプリケーションの設定情報が、xml 形式で保存されている |
プロジェクト直下にある、app フォルダ(上記で登場)は、別名パッケージやアプリケーションとも言われる。詳細は以下の通り。
ファイル&フォルダ名 | 概要 |
build | このアプリだけの build 情報が格納される。TOPの build フォルダと同様に、gradleによって自動生成される部分。 |
libs | ビルドされたアーカイブや、ライブラリなどのビルド結果が格納される。例:android-support-v4.jar など |
src | アプリケーションに関するすべてのソース等を保管する場所 |
app.iml | この app フォルダにおける、設定情報が TOP の iml ファイル同様に xml で保存される。 |
build.gradle | この app における、ビルドスクリプト本体 |
proguard-rules.pro | Proguardという、ソースコードの難読化や未使用のコード部分の削除を行ってくれる機能を on にした場合にそのルールを設定するファイル。 |
※Proguard利用時の build.gradle の設定サンプル
android { buildTypes { release { <- リリースビルドにのみ適用 runProguard true proguardFile file('../proguard-project.txt') proguardFile getDefaultProguardFile('proguard-android.txt') } } }
この app/src フォルダの中には通常2つのフォルダしか存在しない
フォルダ名 | 概要 |
androidTest | junitを利用したテスト用の環境一式。ただし java でしか利用できないので、NDK を利用した Native コードには意味がなし |
main | アプリケーションの本体。すでのアプリデータが保存される場所 |
main 以下のフォルダとファイル構造は以下の通り。また同じ階層に flavorタイプのフォルダも作成される。
フォルダ&ファイル名 | 概要 |
java | AndroidのJavaソースが保存される場所 |
jni | Android NDK を利用した、Native ソースを保存しておく場所 |
jniLibs | Android NDK を利用して作成された、ライブラリファイルなどが保存される場所 |
res | アプリケーションで利用するリソースファイルを入れておく場所 |
assets | アプリケーションからアクセスできる保存領域や、データ領域。 |
AndroidManifest.xml | Androidアプリとしての設定ファイル。ADTの頃と一緒 |
jniフォルダにソースを置くだけで自動コンパイルされるため、android.mk などは必要無し。
プロジェクトトップにある build.gradle に以下の指定が行える。
android.defaultConfig.ndk { moduleName 'xxx' <- libxxx.so をリンクする。 ldLibs "dl", "log" <- リンクするライブラリ stl "gnustl_shared" <- 生成するライブラリの種類 abiFilters "armeabi", "armeabi-v7a" <- CPUアーキテクチャの指定 }
また ndk で利用できる指定は以下のとおり。
設定名 | 引数の例 | 機能 |
moduleName | "helloModule" | モジュールの名前を指定 |
stl | "c++_shared","gnustl_shared","stlport_shared" | Standard Template Library の種類の指定 |
cFlags | "-std=c++11 -fexceptions" | Cコンパイラに渡すフラグが指定できる |
ldLibs | "log", "EGL", "android", "GLESv1_CM", "GLESv2", "OpenSLES" | リンクさせるライブラリを指定 |
abiFilters | "armeabi","armeabi-v7a", "arm64-v8a" | CPUアーキテクチャの指定。カンマで複数指定可能。arm64-v8aは64bit-CPU用 |
android { buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' debuggable false ndk { cFlags cFlags + " -DNDEBUG -DLOG_NDEBUG" } } debug { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' debuggable true ndk { debuggable = true <- デバッグの場合は/初期値 } } } }
このように、ビルドタイプ毎に ndk オプションを設定することが可能。debuggable = true が無いと、build type isn't JNI debuggable というエラーがでる。
productFlavors { hoge { applicationId = 'com.gamvaro.hoge' signingConfig signingConfigs.hoge } fuga { applicationId = 'com.gamvaro.fuga' signingConfig signingConfigs.fuga } }
gradleの文法における文字列結合を利用する。
ndk { cFlags = "-I${project.buildDir}/../src/main/jni/prj1" + "-I${project.buildDir}/../src/main/jni/prj2" }
※注意、文字の後ろの文字結合を表す+記号は、文字の後ろに記入すること。
Studioでは、ADTと違いフォルダ構成に大きな変更が入っている。以前の ADTにおけるプロジェクトでは、通常 projectフォルダ直下に、jni フォルダを作成しそこに、Android.mk を設置することで、ndk-build が自動的にそのフォルダ内の Android.mk を参照していたが、Studio では 下記の場所に移動している。(詳細は上記参照)
Project Top + app + src + main + java + jni + jniLibs + armeabi + armeabi-v7a + mips + x86 + res + assets
ようするに上位に、app と src と main というフォルダ階層が増え、その下に ADT の頃のフォルダが並ぶ。
jniLibs のフォルダ名を変更する場合は、以下の行を追加する。
android { sourceSets.main { <- この main といのは jniLibs.srcDir 'libs' } }
自動的に”src/{sourceSet_name}/”にSourceSetsが作成されます。フォルダの初期値を変更したい場合に利用する。※上項のように sourceSet_name(この場合main、mainは共通の部分)を個別に指定する事も可能
項目名 | 初期値 | 備考 |
manifest.srcFile | 'AndroidManifest.xml' | |
java.srcDirs | 'java' | Javaのソースフォルダ |
resources.srcDirs | 'resources' | java用のリソースフォルダ |
res.srcDirs | 'res' | Android用のリソースフォルダ。通常 res フォルダ |
assets.srcDirs | 'res' | Android用のリソースフォルダ。通常 res フォルダ |
jni.srcDirs | 'jni' | C言語などのNativeコードフォルダ |
jniLibs.srcDirs | 'jniLibs' | soファイルなどのNativeライブラリフォルダ |
aidl.srcDirs | Android インターフェイス定義言語の設定フォルダ |
<project_folder>/app/build/intermediates/ndk/debug/lib
この下に各アーキテクチャ毎の so ファイルが作成される。
一度、ndk-build を通じて作成した、.so ファイルを、jniLibs フォルダにいれ、appフォルダ直下の build.gradle の jni ディレクトリの指定を空にすることで、今後の ndk-build は実行されなくなる。(但し、jniLibs の下はアーキテクチャー毎にフォルダがわかれるので、.so ファイルはアーキテクチャーに合わせて振り分ける)
android { sourceSets { main { jni.srcDirs = [] <- 空にする。 jniLibs.srcDir "src/main/libs" } } }
ちなみに内部的な android.mk(自動生成)は以下に作成される。
/app/build/intermediates/ndk/debug/Android.mk
プロダクトに必要なものを指定
android { ProductFlavors { x86.ndk { abiFilter "x86" } x86_64.ndk { abiFilter "x86_64" } mips.ndk { abiFilter "mips" } mips64.ndk { abiFilter "mips64" } armv7.ndk { abiFilter "armeabi-v7a" } armv8.ndk { abiFilter "arm64-v8a" } arm.ndk { abiFilter "armeabi" } } }
AndroidStudioでは、他のプロジェクトを参照する方法が存在しないため、プロジェクト内に外部ライブラリをモジュールという形で導入する。(例では libpng)
AndroidStudioでプロジェクトを作成後、メニューから、FILE -> New -> New Module と選択しモジュールの作成を指定すると、どのようなモジュールなのかの選択画面が表示されるので、ここで Android Library を指定する。
その後、モジュール名とライブラリ名を指定する。
Application Library Name : Lib PNG ver 1.6.19 Module Name : libpng
その後、プロジェクト作成時と同じ Activityの種類を指定するが、通常は必要ないので、no Activity を選択する。
Android Studioのプロジェクト内にある「app」フォルダを右クリックして、Open Module Settingsを選択します。するとダイアログが表示されるので、Projectタブを選択すると、右にGradle versionが表示されていますので、これを変更することで gradleのバージョンを変更できます。(例:2.4 -> 2.5)※その後Android StudioのWindows下にあるStatusエリアに、updateの情報が表示されます。
具体的には下記のようなエラーメッセージの場合。
NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin. For details, see http://tools.android.com/tech-docs/new-build-system/gradle-experimental. Set "android.useDeprecatedNdk=true" in gradle.properties to continue using the current NDK integration.
gradle.propertiesファイルに以下の行を追加
android.useDeprecatedNdk=true