Cocos2d-x Android開発でPluginProtocolだけ欲しい

自分用の手順書です。
なにか抜けてたら逐次追記します。


## 開発環境
Cocos2d-x 3.3 rc0
NDK r9d

本稿ではCocos2d-x 3.3 rc0を使用していますが、3.0 beta2くらいの頃から使い倒している手段なので、3.xなら大丈夫だと思います。

## やりたいこと

広告を表示させたり、OSのポップアップを表示させたり、外部に遷移させたりなどを行う際、本家のplugin-xが中々使いづらく、且つ開発の進捗も怪しいのでPluginWrapperだけ使いたい。
PluginWrapperはplugin-xで共通で使用されている、UIスレッドでの処理をいい感じにしてくれるコンポーネント。


## 下準備

#### plugin-xをパブリッシュ

空の状態でパブリッシュしたいので、config.shで、余計なプラグインを削除する。
パブリッシュ自体はプロジェクト個別にコピーされたcocos2dリソースからも行えるが、PluginProtocolを全プロジェクト統一して使いたい場合は、本体の方のリソースで行ったほうが良い。


```
$ cd cocos2d/plugin/tools/
$ vi config.sh 

#define plugins array
#export ALL_PLUGINS=("flurry" "umeng" \
#"alipay" "nd91" "googleplay" \
#"admob" \
#"twitter" "weibo" \
#"qh360" "uc" \
#"facebook" "facebookads")

export ALL_PLUGINS=()
...

```

そしてパブリッシュ。
この際、NDK等のパスを聞かれるので適宜入力する。

```

$ ./publish.sh 

Please input the android-ndk path:
/Users/smith/lib/ndk/
Get ANDROID_NDK_ROOT=/Users/smith/lib/ndk

Please input the andoid-sdk path:
/Users/smith/lib/adt-bundle-mac-x86_64-20140702/sdk
Get ANDROID_SDK_ROOT=/Users/smith/lib/adt-bundle-mac-x86_64-20140702/sdk

Please input the ant tool path(such as '/Users/MyAccount/tools/ant/bin'):
/Users/smith/lib/apache-ant-1.9.4/bin
Get ANT_PATH=/Users/smith/lib/apache-ant-1.9.4/bin


```

#### mkファイルを編集

```lang:Android.mk
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

$(call import-add-path,$(LOCAL_PATH)/../../cocos2d)
$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/external)
$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/cocos)

# パスの追加
$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/plugin/publish)

LOCAL_MODULE := cocos2dcpp_shared

LOCAL_MODULE_FILENAME := libcocos2dcpp

LOCAL_SRC_FILES := hellocpp/main.cpp \
                   ../../Classes/AppDelegate.cpp \
                   ../../Classes/HelloWorldScene.cpp

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes

LOCAL_STATIC_LIBRARIES := cocos2dx_static

# .aの追加 PluginProtocol以外に使うものもついでに
LOCAL_WHOLE_STATIC_LIBRARIES += PluginProtocolStatic
LOCAL_WHOLE_STATIC_LIBRARIES += cocosdenshion_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocos_network_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocos_extension_static

include $(BUILD_SHARED_LIBRARY)

$(call import-module,.)

# モジュールの追加 PluginProtocol以外に使うものもついでに
$(call import-module,protocols/android) 
$(call import-module,audio/android)
$(call import-module,network)
$(call import-module,extensions)

```

また、ndkのバージョンとかバグとかstdとかの煩雑な問題から開放されるため、私はSTLをgnustl_staticにすることが習慣になってしまっています。

```lang:Application.mk
#APP_STL := c++_static
APP_STL := gnustl_static
```


#### libPluginProtocolプロジェクトのインポートと参照の追加

Eclipseにプロジェクトをインポートした上で、プロジェクトのプロパティからlibPluginProtocolへの参照を加える

![スクリーンショット 2014-12-17 16.50.39.png](https://qiita-image-store.s3.amazonaws.com/0/42873/fc6cb904-27e5-7dfa-96e5-226c0c4d8f1e.png)

#### antに署名の設定

今回の題目とは関係ないけど、おまけ。

```lang:ant.properties

key.alias.password=my_fantastic_app_password
key.store.password=my_fantastic_app_password
key.store=/Users/smith/keys/apk/my_fantastic_app/my_fantastic_app_key
key.alias=my_fantastic_app_key

```


## 実装

PluginWraperを使用するためには、適宜初期化する必要があります。

#### javaVM

```lang:main.cpp
#include "AppDelegate.h"
#include "cocos2d.h"
#include "platform/android/jni/JniHelper.h"
#include <jni.h>
#include <android/log.h>
#include "PluginJniHelper.h"

#define  LOG_TAG    "main"
#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)

using namespace cocos2d;

void cocos_android_app_init (JNIEnv* env, jobject thiz)
{
    AppDelegate *pAppDelegate = new AppDelegate();
    
    JavaVM* vm;
    env->GetJavaVM(&vm);
    PluginJniHelper::setJavaVM(vm);
}

```

#### Cocos2dxActivityとCocos2dxGLSurfaceView

ClippingNodeとか使ってると、Cocos2dxGLSurfaceViewは必然的に設定することになるんじゃないかと。

```lang:AppActivity.java
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
import org.cocos2dx.plugin.PluginWrapper;

public class AppActivity extends Cocos2dxActivity
{
    @Override public Cocos2dxGLSurfaceView onCreateView()
    {
        Cocos2dxGLSurfaceView glsView = super.onCreateView();
        glsView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);
        
        PluginWrapper.init(this);
        PluginWrapper.setGLSurfaceView(glsView);
        
        H3NativeLifeCycle.applicationDidFinishLaunching();
        
        return glsView;
    }
    
    ...
}
```

## 使い方

GameFeatなど、ContextやActivityを欲しがるSDKにはPluginWrapper.getContext() を与える。

```lang:NiceAdHandler.java
public static void initGamefeat()
{
    gamefeatController = new GameFeatAppController();
    gamefeatController.init(PluginWrapper.getContext());
    gamefeatController.setRefreshInterval(30);
    gamefeatController.activateGF(PluginWrapper.getContext(), false, true, true);
}
```

Viewへの追加はrunOnMainThreadで行う必要がある。
じゃないとクラッシュする。

```lang:NiceAdHandler.java
public static void showIntersticial()
{
    PluginWrapper.runOnMainThread(new Runnable(){
        @Override
        public void run()
        {
            aidController.showDialog(AdController.DialogType.ON_EXIT);
        }
    });
}
```

殊の外、jniのデバッグはめんどいので、とにかくtry / catch(Exception e) でエラーメッセージを見るという残念な手法が推奨される。

## ビルド

通らなかったらごめんなさい。

```
$ cocos run -p android -m release --ap 14
```