OSに依存する処理を行う際に利用するのがJNIです。
これを使えば、OS毎に処理を分けて実装することができます。
主なJniの利用例
- 広告の設置 および表示・非表示処理
- tweet機能
- ランキング機能(GameCenter)
- アプリ内課金処理
- ネットを開く
- スクリーンショットを撮る
今回はcocos2dx[3.x]で、このJNIを実装する方法を紹介します。
利用するコードはGitHubを参考にして下さい。
Github : albatrus/cocos2dx_Jni
Xcode
まずは、XcodeでJavaを呼び出すJniの実装を行います。iOS/Androidで利用できる共通コードを作成
まずは、1つのメソッドでiOS/Android側共に呼び出せるメソッドを作成します。以下のように、ファイルを3つ作成して下さい。
- NativeController.h
- NativeController.cpp
- NativeController.mm
Javaのコードを呼び出すJniを利用するファイルを作成
次にJniを利用するファイルを作成します。- NativeController_JNI.h
- NativeController_JNI.cpp
注意点
[.cpp]のファイルはXcodeがビルドするTargetに含めないで下さい。[jni.h file not found]というエラーが出た時も、これが原因です。
Jniの仕組み
今回のコードの説明です。#include "NativeController_JNI.h" #include "platform/android/jni/JniHelper.h" //パッケージ名を指定 #define CLASS_NAME "org/cocos2dx/cpp/AppActivity" extern "C" { void sendJni(){ cocos2d::JniMethodInfo methodInfo; if (!cocos2d::JniHelper::getStaticMethodInfo(methodInfo,CLASS_NAME,"sendJNI", "()V")) { return; } //Android 5.0 Lolipop ではCallStaticObjectMethodではエラーが出ます。 //methodInfo.env->CallStaticObjectMethod(methodInfo.classID,methodInfo.methodID); methodInfo.env->CallStaticVoidMethod(methodInfo.classID,methodInfo.methodID); } void sendJni2(){ cocos2d::JniMethodInfo methodInfo; if (!cocos2d::JniHelper::getStaticMethodInfo(methodInfo,CLASS_NAME,"sendJNI2", "()V")) { return; } // methodInfo.env->CallStaticObjectMethod(methodInfo.classID,methodInfo.methodID); methodInfo.env->CallStaticVoidMethod(methodInfo.classID,methodInfo.methodID); } }
以前は呼び出すパッケージ名がプロジェクト毎に違っていたのですが、Ver3.xになり共通したパッケージを利用するようになりました。
ですので#includeに関してはどのプロジェクトも共通です。
#include "platform/android/jni/JniHelper.h" //パッケージ名を指定 #define CLASS_NAME "org/cocos2dx/cpp/AppActivity"
呼び出すメソッドの記述
詳しくメソッドを見ていきます。まずは、[NativeController.cpp]で利用するメソッド作成します。
void sendJni(){ }
次に、Java側で呼び出すメソッド名を記載します。
void sendJni(){ cocos2d::JniMethodInfo methodInfo; //今回はsendJNI()を呼び出します。 if (!cocos2d::JniHelper::getStaticMethodInfo(methodInfo,CLASS_NAME,"sendJNI", "()V")) { return; } //methodInfo.env->CallStaticObjectMethod(methodInfo.classID,methodInfo.methodID); methodInfo.env->CallStaticVoidMethod(methodInfo.classID,methodInfo.methodID); }
Eclipse
Ver3.xで、パッケージ名が変わっています。先どの指定したパッケージ名にメソッドを記載します。
public class AppActivity extends Cocos2dxActivity { public static void sendJNI(){ Log.d("coocs2dx Jni","Android action 1"); } public static void sendJNI2(){ Log.d("coocs2dx Jni","Android action 2"); } }
これで完了です。
最後に
今回は、Jniを使って呼び出すメソッドに「引数」「戻り値」はありません。だから非常に簡単なコードが利用できました。
もし、「戻り値」などがひつような場合はこちらを参考にして下さい。
Cocos2d-xにおけるJNI(その2) | ワンダープラネットエンジニア Blog
追記 2015-1-29
[Android 5.0 Lolipop]端末では、下記メソッドが使えません。// CallStaticObjectMethod エラーが出ます methodInfo.env->CallStaticObjectMethod(methodInfo.classID,methodInfo.methodID); //CallStaticVoidMethod こちらを利用する methodInfo.env->CallStaticVoidMethod(methodInfo.classID,methodInfo.methodID);
【参考】
