《快速集成指南》

Android 接入

主要流程

  1. 获取 AnySDK Framework;
  2. 获取 AnySDK JS 绑定文件;
  3. 配置 AnySDK Framework 到项目中;
  4. 配置 AnySDK JS 绑定文件到项目中;
  5. 初始化 AnySDK;
  6. 插件的加载与卸载;
  7. Sample: https://github.com/AnySDK/Sample_JSB (Sample 版本为 Cocos2d-js-3.1)
  8. 框架支持的版本:版本 2.x:Cocos2d-x 2.2.0 及以上的版本;版本 3.x:Cocos2d-js 3.0 及以上版本。

获取 AnySDK Framework

为了集成 AnySDK Framework,请在 AnySDK 客户端的 安妮市场 里,选择 JS(Android) 框架进行下载
打开文件夹,目录如下:
JS 框架目录
下载得到的 AnySDK Framework 框架资源目录内各部分介绍如下图所示:
框架目录结构

获取 AnySDK JS 绑定文件

下载 AnySDK Framework for JS 包后,解压,会有四个不同版本的脚本绑定文件的目录,根据使用的 Cocos2d-js 的版本,来选择相应的绑定文件。 src 下面则是一个 jsb_anysdk.js、jsb_anysdk_constants.js 文件,该文件是对应 c++ 里面定义的枚举变量以及 JS 接口优化代码。(使用的时候,需要添加到 project.json 里面)

"jsList" : [
    "src/resource.js",
    "src/jsb_anysdk.js",
    "src/jsb_anysdk_constants.js",
    "src/app.js"
]

配置 AnySDK Framework 到项目中

拷贝 AnySDK Framework STL 库到 protocols 文件夹

protocols 文件

首先,查看所接入项目的 frameworks/runtime-src/proj.android/jni/Application.mk 文件(注:Cocos2d-x v2.x 和 v3.x,该文件所在文件夹路径不同)第一行找到 STL 库类型设置。 如下图: STL 库类型设置
然后,进入所接入项目的 frameworks/runtime-src/proj.android 目录,新建 protocols 文件夹。根据上面查看到的 STL 类型,选取 AnySDK_Framework_JS/framework/protocols_gnustl_static 库,然后将该目录下的 android 和 include 文件夹拷贝到 protocols 目录。

res 文件

将 AnySDK_Framework_JS/framework/protocols_gnustl_static 目录下的 res 文件里的资源,拷贝到 proj.android/res 目录下,注意选择合并,避免文件覆盖。

class 文件

将 AnySDK_Framework_JS/3.x 目录下的文件拷贝到 proj.android/../Classes 目录下
PS:根据不同版本的引擎拷贝不同的目录下的脚本绑定文件

放置 libPluginProtocol.jar 包

cocos 命令编译的时候,jar 包需要在 libs 目录里,在 proj.android 目录下新建 libs 文件夹,然后将 proj.android/protocols/android 目录下的 libPluginProtocol.jar 移到该目录下。
PS:部分版本 jar 包是放在 jars 目录里。

编辑 Android.mk 文件

Android.mk 文件在 frameworks/runtime-src/proj.android/jni 下面。(注意 v2.x 和 v3.x 的 Cocos2d-x,这个文件的目录不一样)

增加 NDK_MODULE_PATH

不同版本不同编译方式有不同的添加方法,在此提供一个通用的添加方法,不管是哪种方法,只要编译能找到 AnySDK 的库即可。
在 Android.mk 第一行 LOCAL_PATH := $(call my-dir) 下面新加一行代码

LOCAL_PATH := $(call my-dir)
$(call import-add-path,$(LOCAL_PATH)/../)

修改 LOCAL_SRC_FILES

在 LOCAL_SRC_FILES 新增 JS 绑定的 cpp 文件(不同引擎版本的 JS 绑定文件不一样),例:
2.x 版本

LOCAL_SRC_FILES := hellojavascript/main.cpp \
                   ../../Classes/AppDelegate.cpp \
                   ../../Classes/jsb_anysdk_auto.cpp \
                   ../../Classes/jsb_anysdk_manual.cpp

3.0 及以上、3.5 以下版本

LOCAL_SRC_FILES := hellojavascript/main.cpp \
                   ../../Classes/AppDelegate.cpp \
                   ../../Classes/autoanysdkbindings.cpp \
                   ../../Classes/manualanysdkbindings.cpp

3.5 及以上版本

LOCAL_SRC_FILES := hellojavascript/main.cpp \
                   ../../Classes/AppDelegate.cpp \
                   ../../Classes/jsb_anysdk_basic_conversions.cpp \
                   ../../Classes/jsb_anysdk_protocols_auto.cpp \
                   ../../Classes/manualanysdkbindings.cpp

新增 static lib

例:

LOCAL_WHOLE_STATIC_LIBRARIES += PluginProtocolStatic

注:PluginProtocolStatic 请勿使用 LOCAL_STATIC_LIBRARIES,否则会导致 AnySDK 部分函数找不到。

新增 modules

例:

$(call import-module,protocols/android)

添加设置 javaVM 代码

修改 main.cpp 文件(在 jni 下面)

Cocos2d-js-v3.1 及以上版本:

#include "PluginJniHelper.h"

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

using namespace cocos2d;
using namespace anysdk::framework;

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

Cocos2d-x 2.x 版本(proj.android/jni/hellojavascript/main.cpp)、Cocos2d-js-v3.1 之前版本(例如 3.0 在 frameworks/js-binding/cocos2d-x/cocos/platform/android/javaactivity-android.cpp):

#include "PluginJniHelper.h"

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

using namespace cocos2d;
using namespace anysdk::framework;

jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
    JniHelper::setJavaVM(vm);
    PluginJniHelper::setJavaVM(vm);
    return JNI_VERSION_1_4;
}

注:因为 setJavaVM 需要在 onCreate 之前,所以写在 JNI_OnLoad 里肯定没错。Cocos2d-js-v3.1(对应的是 Cocos2d-x 3.3rc0)及其以上版本的 cocos_android_app_init 是在 onCreate 之前的,所以也可以写在这里。3.x 版本头文件需要写全路径,例如 js v3.0 版本 #include "../../../../../runtime-src/proj.android/protocols/android/PluginJniHelper.h"

示例如图

设置 JavaVM

配置 AndroidManifest.xml 添加框架需要的权限

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.RESTART_PACKAGES" />
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />

在 JAVA 层初始化 AnySDK Framework

初始化 AnySDK Framework

首先找到游戏工程的主 Activity,以 Cocos2d-x 引擎游戏为例,主 Activity 即是继承了 cocos2dxActivity 的 Activity。 并在主 Activity 的 onCreate() 方法中新增如下代码来初始化 AnySDK Framework:修改 proj.android/src/org/cocos2dx/javascript/AppActivity.java 文件。

import com.anysdk.framework.PluginWrapper;

public class MainActivity extends Activity{
   protected void onCreate(Bundle savedState)
   {
      super.onCreate(savedState);
      PluginWrapper.init(this); // for plugins
      PluginWrapper.loadAllPlugins(); // 建议在 onCreate 里加载插件,此时会对 SDK 进行初始化
   }
}

注:

  1. 在 Cocos2d-x 3.0 版本中集成 Cocos2dxActivity 之后已经不需要手动实现其他方法,因此如果开发者发现主 Activity 没有 onCreate 方法,就需要自己去重写这个方法(直接拷贝上面的代码片段也可以)。且 super.onCreate(savedState); 请在 PluginWrapper.init(this); 之前调用,因为 init 的时候需要调用 C++ 函数,而 so 文件是在 onCreate 时加载。
  2. AnySDK 的回调函数默认是在主线程,可以在 onCreate 加上 PluginWrapper.setGLSurfaceView(Cocos2dxGLSurfaceView.getInstance()); 将回调改成在 GL 线程,不在 GL 线程里操作界面会有问题。

重写 Activity 生命周期相关方法

  1. 重写 Activity 生命周期相关方法,代码如下:
import android.content.Intent;
import android.os.Bundle;
import android.content.res.Configuration;

import com.anysdk.framework.PluginWrapper;
@Override
protected void onDestroy() {
    PluginWrapper.onDestroy();
    super.onDestroy();
}

@Override
protected void onPause() {
    PluginWrapper.onPause();
    super.onPause();
}

@Override
protected void onResume() {
    PluginWrapper.onResume();
    super.onResume();
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    PluginWrapper.onActivityResult(requestCode, resultCode, data);
    super.onActivityResult(requestCode, resultCode, data);
}

@Override
protected void onNewIntent(Intent intent) {
    PluginWrapper.onNewIntent(intent);
    super.onNewIntent(intent);
}

@Override
protected void onStop() {
    PluginWrapper.onStop();
    super.onStop();
}

@Override
protected void onRestart() {
    PluginWrapper.onRestart();
    super.onRestart();
}

@Override
public void onBackPressed() {
    PluginWrapper.onBackPressed();
    super.onBackPressed();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    PluginWrapper.onConfigurationChanged(newConfig);
    super.onConfigurationChanged(newConfig);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    PluginWrapper.onRestoreInstanceState(savedInstanceState);
    super.onRestoreInstanceState(savedInstanceState);
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    PluginWrapper.onSaveInstanceState(outState);
    super.onSaveInstanceState(outState);
}

@Override
protected void onStart() {
    PluginWrapper.onStart();
    super.onStart();
}

配置 AnySDK JS 绑定文件到项目中

修改 AppDelegate.cpp 文件

3.x 该文件的路径是 frameworks/runtime-src/Classes/AppDelegate.cpp,2.x 路径是 Classes/AppDelegate.cpp
在 sc->start(); 这一行之前 新增:
3.5 及以上版本

sc->addRegisterCallback(register_all_anysdk_framework);
sc->addRegisterCallback(register_all_anysdk_manual);

并引用对应的头文件:

#include "jsb_anysdk_basic_conversions.h"
#include "jsb_anysdk_protocols_auto.hpp"
#include "manualanysdkbindings.hpp"

3.0 及以上、3.5 以下版本

sc->addRegisterCallback(register_all_autoanysdkbindings);
sc->addRegisterCallback(register_all_anysdk_manual);

并引用对应的头文件:

#include "autoanysdkbindings.hpp"
#include "manualanysdkbindings.hpp"

2.x 版本

sc->addRegisterCallback(register_all_anysdk);
sc->addRegisterCallback(register_all_anysdk_manual);

并引用对应的头文件:

#include "jsb_anysdk_auto.hpp"
#include "jsb_anysdk_manual.hpp"

修改结果如图

修改 AppDelegate 文件

在项目中使用 AnySDK

初始化并加载 AnySDK

在 JS 文件中(游戏开始阶段)使用下面几行初始化 AnySDK

//注意:这里 appKey, appSecret, privateKey,要替换成自己打包工具里面的值(登录打包工具,游戏管理界面上显示的那三个参数)。
var appKey = "CED525C0-8D41-F514-96D8-90092EB3899A";
var appSecret = "a29b4f22aa63b8274f7f6e2dd5893d9b";
var privateKey = "963C4B4DA71BC51C69EB11D24D0C7D49";
var oauthLoginServer = "http://oauth.anysdk.com/api/OauthLoginDemo/Login.php";
var agent = anysdk.agentManager;
//init
agent.init(appKey,appSecret,privateKey,oauthLoginServer);
//load
//Android建议 在onCreate 里调用 PluginWrapper.loadAllPlugins();来进行插件初始化
//agent.loadAllPlugins();

获取各个插件

var user_plugin       = agent.getUserPlugin();         //用户系统
var iap_plugins       = agent.getIAPPlugin();          //支付系统
var share_plugin      = agent.getSharePlugin();        //分享系统
var ads_plugin        = agent.getAdsPlugin();          //广告系统
var social_plugin     = agent.getSocialPlugin();       //社交系统
var push_plugin       = agent.getPushPlugin();         //推送系统
var analytics_plugin  = agent.getAnalyticsPlugin();    //统计系统
var crash_plugin      = agent.getCrashPlugin();        //崩溃分析系统
var rec_plugin        = agent.getRECPlugin();          //录屏分享系统
var custom_plugin     = agent.getCustomPlugin();       //自定义系统

卸载 SDK 插件

在游戏结束或者适当的时候,调用 unloadAllPlugins 来卸载 SDK 插件

agent.unloadAllPlugins();

iOS 接入

获取 AnySDK Framework

为了集成 AnySDK Framework,请在 AnySDK 客户端的 安妮市场 里,选择 JS(iOS) 框架进行下载
解压之后,文件内容如下:
框架目录

删除多余的 Targets

目前打包工具只支持单个 Target,若有多个 Targets 会导致打包出来的工程文件缺失,无法正常运行
可在目标上右键选择删除
 Target 配置
如果有其他 Target 所需要用到的同名 .plist 文件,也需要删除,否则打包后工程 AnySDK 文件夹下可能会缺失 .plist 文件
 info.plist 位置
若不想在原工程文件上操作,可以在同级目录下拷贝一份.xcodeproj,并且打开其包内容,删除 xcuserdata 文件夹和 project.xcworkspace 下的 xcuserdata 文件夹,修改 /project.xcworkspace/contents.xcworkspacedata 文件中的 location 值,为改名后的文件名,再对拷贝后的工程文件进行操作
 xcworkspacedata 拷贝

将图标转为 Asset Catalog 形式

在母工程中需要将 icon 转为 Asset Catalog 形式,否则可能导致打包后图标替换错误或者闪屏替换出现问题。
设置 Icon
若按钮为此样式,点击该 Use Asset Catalog 按钮,Xcode 会自动转化原有图标,生成一个 Images.xcassets 文件夹。

在项目中引用 libPluginProtocol

打开您的 iOS 项目(也就是 your-project-name.xcodeproj),一般有两种方式可以引入一个外部的 Framework 文件(参考下面的 1. 添加文件到项目中,2. 添加 lib 到项目中),两种方式都可以。

1. 添加文件到项目中

右键点击项目中的 lib 文件夹,点击 Add Files to “your project name”,之后会弹出选择文件的框,找到 protocols, 选取它,并点击 add,添加 libPluginProtocol.a 就成功了。请不要修改 .a 的文件名(不同框架下文件名可能为 "libPluginProtocol.a","libPluginProtocol_libc++.a" 或 "libPluginProtocol_libstdc++.a"),否则打包时检测框架版本号时会报错。
添加库
添加 protocols 注意要选择 Create groups添加库
PS:如何选择框架版本。
开发者可以在工程配置查询 C++ Standard Library 中查看是 libc++libstdc++compiler-default 来选择相应的库文件。
库配置

2. 添加 lib 到项目中

在 xcode 里面选中你的项目,选择 TARGETS -> Build Phases -> Link Binary With Libraries,点击 +,(如图红色箭头所指),弹出一个界面,点击 Add Other...,之后会弹出选择文件的框,找到 libPluginProtocol.a, 选取它,并点击 open,添加 libPluginProtocol.a 就成功了。(include 文件夹要手动添加到项目中,按照第一种方式)
库链接

引入框架之后如图

引入框架

添加工程配置

打开项目工程配置,添加库的链接参数,在项目⼯程配置,找到 Linking 中的 Linking Other Linker Flags,添加参数:-ObjC
链接设置
注意:如果您使用的是 Cocos2d-x 引擎,在添加 -ObjC 后,可能会有编译报错,类似: 错误提示
此时就要根据不同情况,来添加相应的类库。这里的这个报错,是需要添加库 MediaPlayer.frameworkGameController.framework

框架依赖库

libPluginProtocol 需要依赖以下这几个库

CFNetwork.framework
CoreFoundation.framework
MobileCoreServices.framework
SystemConfiguration.framework
libz.dylib(Xcode7:libz.tbd)
Security.framework

配置 AnySDK JSB 文件到项目中

修改 AppDelegate.cpp 文件

3.x 该文件的路径是 frameworks/runtime-src/Classes/AppDelegate.cpp,2.x 路径是 Classes/AppDelegate.cpp
在 sc->start(); 这一行之前 新增:
3.5 及以上版本

sc->addRegisterCallback(register_all_anysdk_framework);
sc->addRegisterCallback(register_all_anysdk_manual);

并引用对应的头文件:

#include "jsb_anysdk_basic_conversions.h"
#include "jsb_anysdk_protocols_auto.hpp"
#include "manualanysdkbindings.hpp"

3.0 及以上、3.5 以下版本

sc->addRegisterCallback(register_all_autoanysdkbindings);
sc->addRegisterCallback(register_all_anysdk_manual);

并引用对应的头文件:

#include "autoanysdkbindings.hpp"
#include "manualanysdkbindings.hpp"

2.x 版本

sc->addRegisterCallback(register_all_anysdk);
sc->addRegisterCallback(register_all_anysdk_manual);

并引用对应的头文件:

#include "jsb_anysdk_auto.hpp"
#include "jsb_anysdk_manual.hpp"

修改结果如图

修改 AppDelegate 文件
注:随着 Cocos2d-js 的版本升级,这个文件的内容可能不同,但是都是可以添加自定义绑定方法的。

在项目中使用 AnySDK

初始化并加载 AnySDK

在 JS 文件中(游戏开始阶段)使用下面几行初始化 AnySDK

//注意:这里 appKey, appSecret, privateKey,要替换成自己打包工具里面的值(登录打包工具,游戏管理界面上显示的那三个参数)。
var appKey = "CED525C0-8D41-F514-96D8-90092EB3899A";
var appSecret = "a29b4f22aa63b8274f7f6e2dd5893d9b";
var privateKey = "963C4B4DA71BC51C69EB11D24D0C7D49";
var oauthLoginServer = "http://oauth.anysdk.com/api/OauthLoginDemo/Login.php";
var agent = anysdk.agentManager;
//init
agent.init(appKey,appSecret,privateKey,oauthLoginServer);
//load
agent.loadAllPlugins();

获取各个插件

var user_plugin       = agent.getUserPlugin();         //用户系统
var iap_plugins       = agent.getIAPPlugin();          //支付系统
var share_plugin      = agent.getSharePlugin();        //分享系统
var ads_plugin        = agent.getAdsPlugin();          //广告系统
var social_plugin     = agent.getSocialPlugin();       //社交系统
var push_plugin       = agent.getPushPlugin();         //推送系统
var analytics_plugin  = agent.getAnalyticsPlugin();    //统计系统
var crash_plugin      = agent.getCrashPlugin();        //崩溃分析系统
var rec_plugin        = agent.getRECPlugin();          //录屏分享系统
var custom_plugin     = agent.getCustomPlugin();       //自定义系统

卸载 SDK 插件

在游戏结束或者适当的时候,调用 unloadAllPlugins 来卸载 SDK 插件

agent.unloadAllPlugins();

注意不要在 .m 文件中调用 AnySDK 的 Framework

注意不要在 .m 文件中调用 AnySDK 的 Framework,需要修改成 .mm 文件。

CCConsole.h 报错 'thread' file not found

修改 C++ Standard Librarylibc++,并且接入相应的框架。

cocos2dx(V2.2.x)集成注意事项

在修改 other linker flag(添加 -ObjC)和引入 AnySDK 的 Framewrok 之后,有可能会报类似 library not found lluajit 的错误。如图:
错误提示
需做如下修改:
修改配置
此时在编译,会报类似 std::** 的错误,如图:
错误提示
解决办法如图:
修改配置
再次编译后,会报如下图的错误:
错误提示
解决办法如图:
修改配置
至此,编译错误搞定。