facebook twitter hatena line email

Cocos2dx/AndroidNative連携/コールバック

提供: 初心者エンジニアの簡易メモ
2017年4月5日 (水) 18:13時点におけるAdmin (トーク | 投稿記録)による版

移動: 案内検索

サンプルコード

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リスト

JNI Types Java Type
void void
jboolean boolean
jbyte byte
jchar char
jshort short
jint int
jlong long
jfloat float
jdouble double
jobject All Java objects
jclass java.lang.Class objects
jstring java.lang.String objects
jobjectArray Array of objects
jbooleanArray Array of booleans
jbyteArray Array of bytes
jshortArray Array of shorts
jintArray Array of integers
jlongArray Array of longs
jfloatArray Array of floats
jdoubleArray Array of doubles

参考:http://stnguyen.com/cocos2d-x/call-cpp-functions-from-java.html

コールバック関数ファイルについて

明示的にcom_example_helloworld_SampleBridge.hに分けて記載してるが、NativeLauncher.hに一緒にしても問題ない。 ただし、iOSなどではこの関数は使わないので分けたほうが良い。

Unable to find source java classエラーが出た場合

一旦android-project側をclean&buildしてみる。

Execution failed for task ':compileDebugJavaWithJavac'エラーが出た場合

一旦android-project側をclean&buildしてみる。