anysdk-lua快速集成指南

来自AnySDK 文档
跳转至: 导航搜索
本文介绍的是AnySDK Framework 在cocos2d-x lua的集成流程和注意事项(适用于quick-x)。

Android接入

主要流程

1. 获取AnySDK Framework;

2. 获取anysdk-lua绑定文件;

3. 配置AnySDK Framework到项目中;

4. 配置anysdk-lua文件到项目中;

5. 初始化anysdk;

6. 使用各个接口;

7. sample:https://github.com/AnySDK/Sample_Lua (Sample版本为cocos2d-x 3.3rc0)。

8. 如果使用的quick版本有自带AnySDK库,请更新AnySDK最新的库,并改用AnySDK的lua脚本绑定。

9. 使用anysdk-Lua框架的时候,版本2.x:建议使用cocos2d-x v2.2.0及以上的版本;版本3.x,建议使用cocos2d-x v3.0及以上的版本。

获取AnySDK Framework

为了集成AnySDK Framework,请在AnySDK客户端的“安妮市场”里,选择Lua(Android)框架进行下载 目录打开如下:

Lua-protocol.jpg

查看游戏项目使用stl库的版本
以cocos2d-x框架为例,开发者可以在工程目录下jni/application.mk文件第一行找到stl库类型设置
如果此处设置的是 APP_STL := gnustl_static,则表示当前工程以gnu静态库的方式引入使用stl标准库,此时应选择集成protocols_gnustl_static这个文件夹中的框架资源。
如果是 APP_STL := c++_static,则选择集成protocols_c++_static文件夹中的框架资源。
如果是 APP_STL := stlport_static,则应选择集成 protocols_stlport_static文件夹中的框架资源。


下载得到的AnySDK Framework框架资源目录内各部分介绍如下图所示:

AnySDK Framework目录结构.png

获取anysdk-lua绑定文件

下载AnySDK Framework for Lua包后,解压,会有两个2.x和3.x的包,根据使用的cocos2d-x的版本,来选择相应的绑定文件。

src下面则是一个anysdkConst.lua文件,该文件是对应c++里面定义的枚举变量。(使用的时候,需要在文件里面引用 require "anysdkConst" )

拷贝anysdk framework stl库到protocols文件夹

protocols文件

首先,查看项目的frameworks/runtime-src/proj.android/jni/application.mk文件(注:cocos2d-x v2.x和v3.x,该文件所在文件夹路径不同),第一行找到stl库类型设置。 如下图:

Application-mk.png

然后,进入项目的frameworks/runtime-src/proj.android目录,新建protocols文件夹。根据上面查看到的stl类型,选取AnySDK_Framework_Lua/framework/protocols_gnustl_static库,然后将该目录下的android和include文件夹拷贝到protocols目录。

res文件

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

class文件

将AnySDK_Framework_Lua/3.x目录下的文件拷贝到frameworks/runtime-src/Classes目录下

放置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 新增lua绑定的cpp文件: anysdkbindings.cpp 和 anysdk_manual_bindings.cpp,例:

LOCAL_SRC_FILES := hellojavascript/main.cpp \
    ../../Classes/AppDelegate.cpp \
    ../../Classes/anysdkbindings.cpp \
    ../../Classes/anysdk_manual_bindings.cpp
新增 static lib

例:

LOCAL_WHOLE_STATIC_LIBRARIES += PluginProtocolStatic
注:PluginProtocolStatic请勿使用LOCAL_STATIC_LIBRARIES,否则会导致AnySDK部分函数找不到。
新增 modules

例:

$(call import-module,protocols/android)

添加设置javaVM代码

修改main.cpp文件

3.3rc0及其以上版本:

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

2.x版本(proj.android/jni/hellolua/main.cpp)、3.3rc0之前版本(例如3.2在frameworks/cocos2d-x/cocos/platform/android/javaactivity.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里肯定没错。3.3rc0及其以上版本的cocos_android_app_init是在onCreate之前的,所以也可以写在这里。3.x版本头文件需要写全路径,例如3.2版本#include "../../../../runtime-src/proj.android/protocols/android/PluginJniHelper.h"

示例如图
Lua-main.jpg

配置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生命周期相关方法
2.重写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-lua文件到项目中

修改AppDelegate文件

1: 放置anysdkbindings.h、anysdkbindings.cpp、anysdk_manual_bindings.h、anysdk_manual_bindings.cpp这4个文件到Classes文件夹下。

2: 修改AppDelegate.cpp文件(3.x路径是:frameworks/runtime-src/Classes/AppDelegate.cpp,2.x路径是 Classes/AppDelegate.cpp)

在 executeScriptFile; 这一行之前 新增:

3.x版本如下:

   LuaStack* stack = engine->getLuaStack();
   lua_getglobal(stack->getLuaState(), "_G");
   tolua_anysdk_open(stack->getLuaState());
   tolua_anysdk_manual_open(stack->getLuaState());
   lua_pop(stack->getLuaState(), 1);

2.x版本如下:

   CCLuaStack *pStack = pEngine->getLuaStack();
   lua_State *tolua_s = pStack->getLuaState();
   lua_getglobal(tolua_s, "_G");
   tolua_anysdk_open(tolua_s);
   tolua_anysdk_manual_open(tolua_s);
   lua_pop(tolua_s, 1);

并引用对应的头文件:

      #include "anysdkbindings.h"
      #include "anysdk_manual_bindings.h"

示例

Lua-appdelegate.jpg

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

在项目中初始化并加载AnySDK

在lua文件里面使用下面几行 初始化 anysdk:

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

卸载SDK插件

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

agent:unloadAllPlugins();

注意事项

isFunctionSupported的使用

并不是所有的函数都需要这样判断是否支持。像login,就直接调用即可。

IOS接入

获取AnySDK Framework

为了集成AnySDK Framework,请在AnySDK客户端的“安妮市场”里,选择Lua(iOS)框架进行下载
下载后建议将框架拷贝到其他位置,由于下载文件夹带有空格,可能会导致工程库的搜索路径因为空格被分成两部分,导致编译错误
打开文件夹,内容如下:
Lua-protocol-ios.jpg

删除多余的Targets

目前打包工具只支持单个Target,若有多个Targets会导致打包出来的工程文件缺失,无法正常运行
可在目标上右键选择删除

UniTarget.png

如果有其他Target所需要用到的同名.plist文件,也需要删除,否则打包后工程AnySDK文件夹下可能会缺失.plist文件

UniTarget2.png

若不想在原工程文件上操作,可以在同级目录下拷贝一份.xcodeproj,并且打开其包内容,删除xcuserdata文件夹和project.xcworkspace下的xcuserdata文件夹,修改/project.xcworkspace/contents.xcworkspacedata文件中的location值,为改名后的文件名,再对拷贝后的工程文件进行操作

IOSProcess02.png

将图标转为Asset Catalog形式

在母工程中需要将Icon转为Asset Catalog形式,否则可能导致打包后图标替换错误或者闪屏替换出现问题

IconXcassets.png

若按钮为此样式,点击该Use Asset Catalog按钮,Xcode会自动转化原有图标,生成一个Images.xcassets文件夹

在项目中引用libPluginProtocol

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

1: 添加文件到项目中

目前2.0以上版本下载目录在文稿目录下的/AnySDK Files下,由于默认目录带空格,直接导入库文件可能导致搜索路径错误,请将下载后的Framework拷到工程目录下。

一:右键点击 项目中的 lib文件夹,点击“Add Files to “your project name””,之后会弹出选择文件的框,找到protocols, 选取它,并点击 add,添加libPluginProtocol.a就成功了。

请不要修改.a的文件名(不同框架下文件名可能为"libPluginProtocol.a", "libPluginProtocol_libc++.a"或 "libPluginProtocol_libstdc++.a"),否则打包时检测框架版本号时会报错

Add-file.jpg
添加protocols注意要选择 "Create groups".
Addprotocols.jpg

PS:如何选择框架版本
开发者可以在工程配置查询C++ Standard Library 中查看是libc++ 、libstdc++ 、compiler-default来选择相应的库文件 编译设置库.jpg

2: 添加 lib 到项目中

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

引入框架之后如图

Anysdk lua proj.jpg

添加工程配置

打开项目工程配置,添加库的链接参数,在项目⼯程配置中,找到
Linking中的Linking Other Linker Flags,添加参数: -ObjC

Ios linking.jpg

注意:如果您使用的是cocos2d-x引擎,在添加 -ObjC 后,可能会有编译报错,类似:
Ios cocos error.jpg

此时就要根据不同情况,来添加相应的类库。这里的这个报错,是需要添加库 MediaPlayer.framework和 GameController.framework。

框架依赖库

libPluginProtocol需要依赖以下这几个库
CFNetwork.framework
CoreFoundation.framework
MobileCoreServices.framework
SystemConfiguration.framework
libz.tbd

配置anysdk-lua文件到项目中

修改AppDelegate文件

1: 放置anysdkbindings.h、anysdkbindings.cpp、anysdk_manual_bindings.h、anysdk_manual_bindings.cpp这4个文件到Classes文件夹下。

2: 修改AppDelegate.cpp文件(3.x路径是:frameworks/runtime-src/Classes/AppDelegate.cpp,2.x路径是 Classes/AppDelegate.cpp)

在 executeScriptFile; 这一行之前 新增:

3.x版本如下:

   LuaStack* stack = engine->getLuaStack();
   lua_getglobal(stack->getLuaState(), "_G");
   tolua_anysdk_open(stack->getLuaState());
   tolua_anysdk_manual_open(stack->getLuaState());
   lua_pop(stack->getLuaState(), 1);

2.x版本如下:

   CCLuaStack *pStack = pEngine->getLuaStack();
   lua_State *tolua_s = pStack->getLuaState();
   lua_getglobal(tolua_s, "_G");
   tolua_anysdk_open(tolua_s);
   tolua_anysdk_manual_open(tolua_s);
   lua_pop(tolua_s, 1);

并引用对应的头文件:

      #include "anysdkbindings.h"
      #include "anysdk_manual_bindings.h"

示例

Lua-appdelegate.jpg

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

在项目中初始化并加载AnySDK

在lua文件里面使用下面几行 初始化 anysdk:

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

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

agent:unloadAllPlugins();

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

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

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

在修改other linker flag(添加-ObjC)和引入anysdk的framewrok之后,有可能会报类似library not found lluajit的错误。如图
Luajit-notfound.jpg
需做如下修改:
Luajit-notfound1.jpg
此时在编译,会报类似std::**的错误,如图:
Std-error.jpg
解决办法如图:
Std-error1.jpg
再次编译后,会报如下图的错误:
Cocos-error.jpg
解决办法如图:
Cocos-error1.jpg

至此,编译错误搞定。