Cocos2dx/AndroidNative連携/コールバック
サンプルコード
Delegateを使ったコールバックのサンプル
-Classes/SampleDelegate.h
#ifndef Helloworld_SampleDelegate_h #define Helloworld_SampleDelegate_h class SampleDelegate { public: virtual void onCustomEvent(const char* str) = 0; }; #endif
SampleDelegate.cppは不要
-Classes/NativeLauncher.h
#ifndef Helloworld_NativeLauncher_h #define Helloworld_NativeLauncher_h extern "C" { class NativeLauncher { public: static void launchCallbackNative(); // コールバック呼び出しメソッド static void setDelegate(SampleDelegate*); static SampleDelegate* getDelegate(); }; } #endif
-Classes/NativeLauncher.cpp
#include "NativeLauncher.h" #include <jni.h> #include "platform/android/jni/JniHelper.h" #include "SampleDelegate.h" #define CLASS_NAME "org/cocos2dx/cpp/AppActivity" extern "C" { SampleDelegate* mDelegate; void NativeLauncher::launchCallbackNative() { cocos2d::JniMethodInfo t; if (cocos2d::JniHelper::getStaticMethodInfo(t, CLASS_NAME, "launchCallbackNative", "()V")) { t.env->CallStaticVoidMethod(t.classID, t.methodID); t.env->DeleteLocalRef(t.classID); } } void NativeLauncher::setDelegate(SampleDelegate* delegate) { mDelegate = delegate; } SampleDelegate* NativeLauncher::getDelegate() { return mDelegate; } }
-Classes/com_example_helloworld_SampleBridge.h
#include <jni.h> #ifndef _Included_com_example_helloworld_SampleBridge #define _Included_com_example_helloworld_SampleBridge extern "C" { JNIEXPORT void JNICALL Java_com_example_helloworld_SampleBridge_cocosOnCustomEvent(JNIEnv*, jclass, jstring); } #endif // com_example_helloworld_SampleBridge
-Classes/com_example_helloworld_SampleBridge.cpp
#include "cocos2d.h" #include "com_example_helloworld_SampleBridge.h" #include "NativeLauncher.h" USING_NS_CC; extern "C" { JNIEXPORT void JNICALL Java_com_example_helloworld_SampleBridge_cocosOnCustomEvent(JNIEnv* env, jclass clazz, jstring srcj) { const char *message = env->GetStringUTFChars(srcj, NULL); log("success com_example_helloworld_SampleBridge message=%s", message); // launchCallbackNativeMessage NativeLauncher::getDelegate()->onCustomEvent(message); } }
-Classes/HelloWorldScene.h
SampleDelegateをimplementし、onCustomEventメソッドを追加する
class HelloWorld : public cocos2d::Layer, SampleDelegate { public: static cocos2d::Scene* createScene(); virtual bool init(); // a selector callback void menuCloseCallback(cocos2d::Ref* pSender); void menuLogCallback(cocos2d::Ref* pSender); void onCustomEvent(const char*); // implement the "static create()" method manually CREATE_FUNC(HelloWorld); };
-Classes/HelloWorldScene.cpp
#include "NativeLauncher.h" bool HelloWorld::init() { // 略 auto logItem = MenuItemImage::create( "CloseNormal.png", "CloseSelected.png", CC_CALLBACK_1(HelloWorld::menuLogCallback, this)); logItem->setPosition(Vec2(origin.x + visibleSize.width - logItem->getContentSize().width/2 , origin.y + visibleSize.height - logItem->getContentSize().height/2)); auto logmenu = Menu::create(logItem, NULL); logmenu->setPosition(Vec2::ZERO); this->addChild(logmenu, 1); // 略 } void HelloWorld::menuLogCallback(Ref* pSender) { NativeLauncher::launchCallbackNative(); } void HelloWorld::onCustomEvent(const char* message) { log("onCustomEvent delegate '%s'", message); }
-proj.android-studio/app/src/org/cocos2dx/cpp/AppActivity.java
import com.example.helloworld.SampleBridge; public class AppActivity extends Cocos2dxActivity { public static void launchCallbackNative() { System.out.println("launchCallbackNative()"); (new SampleBridge()).onCustomEvent("launchCallbackNativeMessage"); } }
-proj.android/jni/Android.mk
LOCAL_SRC_FILES := hellocpp/main.cpp \ ../../Classes/AppDelegate.cpp \ ../../Classes/HelloWorldScene.cpp \ ../../Classes/NativeLauncher.cpp \ ../../Classes/com_example_helloworld_SampleBridge.cpp
NativeLauncher.cppとcom_example_helloworld_SampleBridge.cppを追加
-proj.android-studio/app/jni/Android.mk
LOCAL_SRC_FILES := hellocpp/main.cpp \ ../../../Classes/AppDelegate.cpp \ ../../../Classes/HelloWorldScene.cpp \ ../../../Classes/NativeLauncher.cpp \ ../../../Classes/com_example_helloworld_SampleBridge.cpp
NativeLauncher.cppとcom_example_helloworld_SampleBridge.cppを追加
-proj.android-studio/app/src/com/example/helloworld/SampleBridge.java
package com.example.helloworld; /** * androidでは(new SampleBridge).onCustomEvent();で呼び出し可能 */ public class SampleBridge { private static native void cocosOnCustomEvent(String message); public void onCustomEvent(final String message) { Thread thread = new Thread(new Runnable() { @Override public void run() { System.out.println("SampleBridge.onCustomEvent"); SampleBridge.cocosOnCustomEvent(message); } }); thread.start(); } }
typeリスト
{ |- ! 行見出し1 | セル1A || セル1B || セル1C |- ! 行見出し2 | セル2A || セル2B || セル2C |} | JNI Types || Java Type | void || void | jboolean || boolean
コールバック関数ファイルについて
明示的にcom_example_helloworld_SampleBridge.hに分けて記載してるが、NativeLauncher.hに一緒にしても問題ない。 ただし、iOSなどではこの関数は使わないので分けたほうが良い。
Unable to find source java classエラーが出た場合
一旦android-project側をclean&buildしてみる。