Unityプラグインを開発しよう:その4:プラグイン解析(Android/Java版) | U-CREATES.の「たぶん」まいにち制作中。

U-CREATES.の「たぶん」まいにち制作中。

◆Webサイト、スマートフォンアプリ制作をしている個人事業主のブログです。
◆オフィシャルWebサイトはこちら。
http://u-creates.com/

前回までにUnityプラグイン(iOS版)の検証が完了したので、今回はUnityプラグイン(Android/Java版)を検証してみようと思います。iOS版と同じくUnityの公式ドキュメントに掲載されているプラグインのサンプルのうち、Android版の解析をします。静的/動的解析を実施したところ、ソースコード群(CallJavaCode.cs、NativeJavaBridge.cpp、JavaClass.java)のうち、iOS版でポイントだったextern修飾子DllImportAttribute、さらにJNIが重要な役割を担っていることがわかりました。

【公式ドキュメントから抜粋したUnityプラグイン開発でのポイントとなる機能】
◆extern修飾子
一般に、相互運用サービスを使用してアンマネージ コードを呼び出すときに、DllImport 属性と共に使用します。
◆DllImport
属性付きメソッドがアンマネージ ダイナミックリンク ライブラリ (DLL) によって静的エントリ ポイントとして公開されることを示します。
◆JNI
Java 仮想マシン (VM) で実行される Java コードが C、C++、アセンブリ言語など他のプログラミング言語で書かれたアプリケーションやライブラリと相互運用できるようになります。

JNI、公開している事例のうち、何点かで利用していますが、JavaからC++を呼ぶ場合C++からJavaを呼ぶ場合の双方を実装しています。実装してみると連携の意味がわかってきますね。

上記を図にしてみると



Androidプラグインの世界はiOS版プラグインよりもスケールが大きいですね。

また、iOS版と比較すると以下の点に注意して開発をしなければならないようです。

【Unityプラグイン(Android/Java版)開発の注意点】
◆DllImportへ指定する外部モジュール名は、Android版の場合、iOS版で指定した「__Internal」ではなく、Shared Object名のようです。
iOS版に倣ってPlugins/AndroidへJavaコードを格納しただけだと動作しないようです。なのでjarファイル(aarファイルでも可)へビルドしてAndroidフォルダへインポートします。

また、公式ドキュメントによると下記のような便利な機能も提供されているようです。公式サンプルに倣ってUnManagedCode経由でJNIを利用するよりも下記を利用した方が簡単そうですね。

【Unityから提供されている便利そうなJNIインターフェイス群】
AndroidJNI
MonoでのJNIインターフェースだそうです。JNIメソッドそれぞれに対応している印象です。
AndroidJNIHelper
JNIのヘルパだそうです。配列のマーシャリングには威力を発揮しそうです。
AndroidJavaClass
Unityでのjava.lang.Classだそうです。
AndroidJavaObject
Unityでのjava.lang.Objectだそうです。

「なんだか全部便利そう」な印象ですが、AndroidJavaClassとAndroidJavaObjectは公式ドキュメント「AndroidJavaObject や AndroidJavaClass は AndroidJNI や AndroidJNIHelper を組み合わせて構成されています。」と記載されているので特に便利そうです。

理屈は頭の中に大体格納されたようなので、実装してみます。

【テストプラグインの実装:Unityプラグイン(Android/Java版)】
◆実装はこれです。
◆検証したところ、AndroidJavaClassだと、どうもユーザー定義Javaクラスは動作しない(java.lang.Classの公式ドキュメントを読んでも不明)ので、AndroidJavaObjectで呼び出しています。
Javaコードのテストプラグインです。iOSプラグインと同様に単純に四則演算をして、演算結果を返すだけのとても簡単な実装です。
◆AndroidSDKは、gradleのリンクへsdk/platformsに格納されている、該当するAPIレベル(事例では18)のandroid.jarファイル経由で利用しています。

このような実装を施したUnityテストプラグイン(Android/Java版)を、手元にあるAndroid(GalaxyS5/Android6.0.1)へインストールして動かしてみると、

JVM上で行った演算結果が表示されましたね(UnityEditorで実行すると0が返却されます。)。

ログにも呼び出し経緯が記録されました。

ログはAndroidSDKから提供されているLogという機能を用いて出力しているので、UnityプラグインでAndroidSDKを利用することが可能だということが実証されました。

・・・検証により、Unityプラグイン(Android/Java版)の開発が実現できそうです。次回はUnityプラグイン(Android/Kotlin版)を検証してみたいと思います。