【cocos2dx】Jniを利用してJavaのコードを呼び出す

OSに依存する処理を行う際に利用するのがJNIです。 これを使えば、OS毎に処理を分けて実装することができます。

主なJniの利用例

  • 広告の設置 および表示・非表示処理
  • tweet機能
  • ランキング機能(GameCenter)
  • アプリ内課金処理
  • ネットを開く
  • スクリーンショットを撮る

今回はcocos2dx[3.x]で、このJNIを実装する方法を紹介します。

利用するコードはGitHubを参考にして下さい。 Github : albatrus/cocos2dx_Jni

Xcode

まずは、XcodeJavaを呼び出す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に含めないで下さい。

2014-6-13-fdsasa.png

[jni.h file not found]というエラーが出た時も、これが原因です。

Jniの仕組み

今回のコードの説明です。 [c]

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);


}

} [/c]

以前は呼び出すパッケージ名がプロジェクト毎に違っていたのですが、Ver3.xになり共通したパッケージを利用するようになりました。 ですので#includeに関してはどのプロジェクトも共通です。 [c]

include "platform/android/jni/JniHelper.h"

//パッケージ名を指定

define CLASS_NAME "org/cocos2dx/cpp/AppActivity"

[/c]

呼び出すメソッドの記述

詳しくメソッドを見ていきます。 まずは、[NativeController.cpp]で利用するメソッド作成します。 [c] void sendJni(){

} [/c]

次に、Java側で呼び出すメソッド名を記載します。 [c] 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);

} [/c]

Eclipse

Ver3.xで、パッケージ名が変わっています。

2014-6-12-fdsasd

先どの指定したパッケージ名にメソッドを記載します。 [c] 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");

}

} [/c]

これで完了です。

最後に

今回は、Jniを使って呼び出すメソッドに「引数」「戻り値」はありません。 だから非常に簡単なコードが利用できました。 もし、「戻り値」などがひつような場合はこちらを参考にして下さい。 Cocos2d-xにおけるJNI(その2) | ワンダープラネットエンジニア Blog

追記 2015-1-29

[Android 5.0 Lolipop]端末では、下記メソッドが使えません。 [c] // CallStaticObjectMethod エラーが出ます methodInfo.env->CallStaticObjectMethod(methodInfo.classID,methodInfo.methodID);

//CallStaticVoidMethod こちらを利用する methodInfo.env->CallStaticVoidMethod(methodInfo.classID,methodInfo.methodID); [/c]

【参考】