Android Gradle プラグイン 0.7.2 でビルド済みの JNI 共有ライブラリを扱えるようになった
「New Build System - Android Tools Project Site」 に書かれているように、Android Gradle プラグイン 0.7.2 から、ビルド済みの JNI 共有ライブラリ (.so ファイル) を配置する jniLibs フォルダがソースセットに追加されました。
- Add jniLibs folder to source sets for prebuilt .so files.
JNI とは
Java Native Interface のことで、Java とネイティブコード (C や C++ で書かれたコード) の間のインターフェイスとして定義されています。 例えば、JNI によりネイティブの動的共有ライブラリを Java から使ったりできます。 Android アプリ開発においても、JNI を使用できます。
自分で Android アプリ用のネイティブコードを書く場合は NDK を使ってビルドしたりするわけですが、今回は予めビルドされている JNI 共有ライブラリを使う話をします。
JNI 共有ライブラリを使う方法
これまで、Android Gradle プラグインではビルド済みの JNI 共有ライブラリ (.so ファイル) を Android アプリのパッケージに組み込む方法が提供されていませんでした。 それが、冒頭に書いたように 0.7.2 で追加されたようです。
デフォルトのディレクトリ配置だと、JNI 共有ライブラリ (.so ファイル) を置くためのディレクトリは src/main/jniLibs になります。
サンプルコードと説明
「New Build System - Android Tools Project Site」 の一番下にサンプルコードのリンクがいくつかありますが、その中の gradle-samples-0.7.3.zip に jniLibs を使うサンプルプロジェクトが入っています。 gradle-samples-0.7.3/ndkPrebuilts がそれです。 ディレクトリの中を見ると src/main/jniLibs ディレクトリの中に armeabi や armeabi-v7a、mips、x86 というアーキテクチャごとのディレクトリが入っていて、それぞれの中に libhello-jni.so ファイルが入っています。
アーキテクチャごとのディレクトリは上に書いた 4 つ全てが必要なわけではなく、対象となるアーキテクチャのディレクトリだけ作ればよいです。 また、src/main/java ディレクトリの位置を変更できるように、build.gradle に次のように記述することで src/main/jniLibs ディレクトリの位置を変更できます。
android {
sourceSets {
main {
jniLibs.srcDirs = ['jniLibs']
}
参考
Gradle でビルドする際に JNI 共有ライブラリをパッケージに含める方法を調べると、自分でそういうタスクを定義するというような情報がいろいろ出てきます。 (昔はサポートされてなかったため。)
- gradle - Include .so library in apk in android studio - Stack Overflow
- Android studio, gradle and NDK - Stack Overflow
- New way to hack ndk so libs copy when using gradle plugin 0.4.0+ (Google Groups)
「Android Gradle プラグイン 0.7.2 でサポートされたよー」 ということが追記されてて非常にありがたかったです。
例: mediba ad の Android SDK
ビルド済みの JNI 共有ライブラリを使う場面の一つの例としては mediba ad の Android SDK があります。
ドキュメントには、
プロジェクトフォルダ内に"libs"フォルダを作成し、libsフォルダ内に"armeabi"フォルダを作成して頂き、libsフォルダ内にJARファイル、armeabiフォルダ内にsoファイルをコピーして「Add JARs...」でJARファイルを指定しても問題ありません。
と書かれていますが、Gradle でビルドする場合は、src/main/jniLibs ディレクトリ *1 下に armeabi ディレクトリを置く、ということになります。
*1:デフォルトのディレクトリ配置の場合。 変更可能。