facebook twitter hatena line email

「Cocos2dx/AndroidNative連携/コールバック」の版間の差分

提供: 初心者エンジニアの簡易メモ
移動: 案内検索
(サンプルコード)
(Admin がページ「Cocos2dx/AndroidNative実行/コールバック」を「Cocos2dx/AndroidNative連携/コールバック」に、リダイレクトを残さずに移動しました)
 
(同じ利用者による、間の39版が非表示)
行1: 行1:
 
==サンプルコード==
 
==サンプルコード==
-Classes/com_example_helloworld_SampleBridge.h
+
Delegateを使ったコールバックのサンプル
#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*, jobject, jstring);
+
}
+
#endif // com_example_helloworld_SampleBridge
+
  
-Classes/com_example_helloworld_SampleBridge.cpp
+
-Classes/SampleDelegate.h
  #include "com_example_helloworld_SampleBridge.h"
+
  #ifndef Helloworld_SampleDelegate_h
  extern "C" {
+
#define Helloworld_SampleDelegate_h
     JNIEXPORT void JNICALL Java_com_example_helloworld_SampleBridge_cocosOnCustomEvent(JNIEnv* env, jobject thiz, jstring srcj) {
+
class SampleDelegate
        const char *message = env->GetStringUTFChars(srcj, NULL);
+
  {
        log("success com_example_helloworld_SampleBridge message=" + message);
+
public:
    }
+
     virtual void onCustomEvent(const char* str) = 0;
  }
+
};
 +
  #endif
 +
 
 +
SampleDelegate.cppは不要
  
 
-Classes/NativeLauncher.h
 
-Classes/NativeLauncher.h
行26: 行22:
 
     public:
 
     public:
 
         static void launchCallbackNative(); // コールバック呼び出しメソッド
 
         static void launchCallbackNative(); // コールバック呼び出しメソッド
 +
        static void setDelegate(SampleDelegate*);
 +
        static SampleDelegate* getDelegate();
 
     };
 
     };
 
  }
 
  }
行34: 行32:
 
  #include <jni.h>
 
  #include <jni.h>
 
  #include "platform/android/jni/JniHelper.h"
 
  #include "platform/android/jni/JniHelper.h"
 +
#include "SampleDelegate.h"
 
  #define CLASS_NAME "org/cocos2dx/cpp/AppActivity"
 
  #define CLASS_NAME "org/cocos2dx/cpp/AppActivity"
 
  extern "C" {
 
  extern "C" {
 +
    SampleDelegate* mDelegate;
 
     void NativeLauncher::launchCallbackNative()
 
     void NativeLauncher::launchCallbackNative()
 
     {
 
     {
行43: 行43:
 
             t.env->DeleteLocalRef(t.classID);
 
             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
 
-Classes/HelloWorldScene.h
  class HelloWorld : public cocos2d::Layer
+
 
 +
SampleDelegateをimplementし、onCustomEventメソッドを追加する
 +
  class HelloWorld : public cocos2d::Layer, SampleDelegate
 
  {
 
  {
 
  public:
 
  public:
行55: 行87:
 
     void menuCloseCallback(cocos2d::Ref* pSender);
 
     void menuCloseCallback(cocos2d::Ref* pSender);
 
     void menuLogCallback(cocos2d::Ref* pSender);
 
     void menuLogCallback(cocos2d::Ref* pSender);
 +
    void onCustomEvent(const char*);
 
     // implement the "static create()" method manually
 
     // implement the "static create()" method manually
 
     CREATE_FUNC(HelloWorld);
 
     CREATE_FUNC(HelloWorld);
行78: 行111:
 
  {
 
  {
 
     NativeLauncher::launchCallbackNative();
 
     NativeLauncher::launchCallbackNative();
 +
}
 +
void HelloWorld::onCustomEvent(const char* message) {
 +
    log("onCustomEvent delegate '%s'", message);
 
  }
 
  }
  
行93: 行129:
 
                     ../../Classes/AppDelegate.cpp \
 
                     ../../Classes/AppDelegate.cpp \
 
                     ../../Classes/HelloWorldScene.cpp \
 
                     ../../Classes/HelloWorldScene.cpp \
                     ../../Classes/NativeLauncher.cpp
+
                     ../../Classes/NativeLauncher.cpp \
NativeLauncher.cppを追加
+
                    ../../Classes/com_example_helloworld_SampleBridge.cpp
 +
NativeLauncher.cppとcom_example_helloworld_SampleBridge.cppを追加
  
-proj.android-studio/jni/Android.mk
+
-proj.android-studio/app/jni/Android.mk
 
  LOCAL_SRC_FILES := hellocpp/main.cpp \
 
  LOCAL_SRC_FILES := hellocpp/main.cpp \
                     ../../Classes/AppDelegate.cpp \
+
                     ../../../Classes/AppDelegate.cpp \
                     ../../Classes/HelloWorldScene.cpp \
+
                     ../../../Classes/HelloWorldScene.cpp \
                     ../../Classes/NativeLauncher.cpp
+
                     ../../../Classes/NativeLauncher.cpp \
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
 
-proj.android-studio/app/src/com/example/helloworld/SampleBridge.java
行122: 行160:
 
  }
 
  }
  
==参考==
+
==コールバック関数ファイルについて==
https://techblog.ca-reward.co.jp/2017/02/post-140.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してみる。

2017年4月11日 (火) 10:10時点における最新版

サンプルコード

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

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

明示的に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してみる。