作者:Jack(JCracker) 邮箱:[email protected]
作者很赖还是不想上传图片 需要图片和配置实例的来这里下载:下载
在正式开始项目前,需要对各个基础模块做出Demo,本文档记录的是在写通用网络模块时候,WIN平台和Android平台联调碰到的问题。
1. WIN平台
WIN平台调试起来非常方便 一般不会出现什么问题。但是因为首先做的是win平台。所以不需要自己手写配置文件(也就是这个问题,导致在移植到android时出现一系列问题)
在win平台中,我是依照如下步骤操作
A. 创建核心库libGameNet:直接创建cocos2d-x项目,删除不需要的其他目录,剩下结构如图所示
B. 创建应用层:直接创建cocos2d-x项目,保留所有创建文件。
其中libGameNet是后一步拷贝过来的
C. 拷贝libGameNet到NetworkDemo中(见上一步的截图)。
D. 因为libGameNet要负责Protobuffer的序列化和反序列化,因此依赖于protobuffer。同时为了方便Network也使用protobuffer,将protobuffer2.5.0复制到networkDemo下的cocos2d/external/ 如下图:
E. 打开networkDemo,添加项目依赖 protobuffer和 libgamenet (添加办法请百度)
F. 因为libGameNet是直接创建cocos2d-x项目生成的。模式是exe格式。这里需要设置为lib模式。Protobuffer自带的vsproject已经指定其为lib 不需要自己配置
G. libGameNet添加libProtobuffer引用
H. 为networkDemo添加libGameNet引用
I. 其中具体涉及的代码略过,编译运行。
其中左边是服务端 右边是客户端。
服务端接受ok
设置断点观察服务端返回protobuffer的值。 确实返回了jcracker0 和jcarcker1
J. 自此 win平台ok
1. 在上面的操作中win平台基本可以平稳的跑起来。测试了在多线程和数据包过大情况下数据的传输。基本没问题。下载移植到android平台。总体流程是。编写libGameNet的android.mk-->解决ant构建问题(可选,如果用vs2012+visual GDB方式打包的话)-->导入eclipse--->解决eclipse问题-->解决NDK编译问题-->生成apk--->利用vs2012+visual GDB联调(具体联调 可参见visual GDB 官方文档),
2. 另一个文档可参考http://my.oschina.net/wpracker/blog/295677
3. 具体来讲
a) Protobuffer的android.mk在以前写过 可以直接拿过来用,这里留一份备用:
在使用全新环境时,记得./configure 一次protobffer 生成必要文件
Protobuffer android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#目标
TARGET_CPU_ABI := armeabi
#TARGET_CPU_ABI := armeabi-v7a
#TARGET_CPU_ABI := armeabi-v7a-hard
#TARGET_CPU_ABI := armeabi
#设置c++11头文件路径和链接路径
prebuilt_stdcxx_PATH := E:\android-ndk-r9d-windows-x86_64\android-ndk-r9d\sources\cxx-stl\gnu-libstdc++\4.8
LOCAL_C_INCLUDES += \
$(prebuilt_stdcxx_PATH)/include \
$(prebuilt_stdcxx_PATH)/libs/$(TARGET_CPU_ABI)/include
LOCAL_C_INCLUDES += E:\ylss\project\NewStartDemo\NetworkDemo\NetworkDemo\cocos2d\external\protobuf-2.5.0\src
$(warning $(prebuilt_stdcxx_PATH))
#LOCAL_LDFLAGS += -L$(prebuilt_stdcxx_PATH)/libs/$(TARGET_CPU_ABI) -lgnustl_static -lsupc++
LOCAL_STATIC_LIBRARIES += -L$(prebuilt_stdcxx_PATH)/libs/$(TARGET_CPU_ABI) -lgnustl_static -lsupc++
LOCAL_MODULE := protobuf_static
LOCAL_MODULE_FILENAME := libprotobuf
LOCAL_CPP_EXTENSION := .cc
LOCAL_SRC_FILES := \
src/google/protobuf/io/coded_stream.cc\
src/google/protobuf/stubs/common.cc \
src/google/protobuf/descriptor.cc \
src/google/protobuf/descriptor.pb.cc\
src/google/protobuf/descriptor_database.cc\
src/google/protobuf/dynamic_message.cc\
src/google/protobuf/extension_set.cc\
src/google/protobuf/extension_set_heavy.cc\
src/google/protobuf/generated_message_reflection.cc \
src/google/protobuf/generated_message_util.cc \
src/google/protobuf/io/gzip_stream.cc \
src/google/protobuf/compiler/importer.cc\
src/google/protobuf/message.cc\
src/google/protobuf/message_lite.cc \
src/google/protobuf/stubs/once.cc \
src/google/protobuf/compiler/parser.cc\
src/google/protobuf/io/printer.cc \
src/google/protobuf/reflection_ops.cc \
src/google/protobuf/repeated_field.cc \
src/google/protobuf/service.cc\
src/google/protobuf/stubs/structurally_valid.cc \
src/google/protobuf/stubs/strutil.cc\
src/google/protobuf/stubs/substitute.cc \
src/google/protobuf/stubs/stringprintf.cc \
src/google/protobuf/text_format.cc\
src/google/protobuf/io/tokenizer.cc \
src/google/protobuf/unknown_field_set.cc\
src/google/protobuf/wire_format.cc\
src/google/protobuf/wire_format_lite.cc \
src/google/protobuf/io/zero_copy_stream.cc\
src/google/protobuf/io/zero_copy_stream_impl.cc \
src/google/protobuf/io/zero_copy_stream_impl_lite.cc
#LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include/protobuf
#LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/protobuf
#LOCAL_CFLAGS := -std=c99
#LOCAL_CFLAGS += -std=c++11 -stdlib=libstdc++ -Wno-error=c++11-narrowing
include $(BUILD_STATIC_LIBRARY)
b) libGameNet的android.mk变化较大不能再原来基础上修改。
#LOCAL_PATH := $(call my-dir)
LOCAL_PATH := E:\ylss\project\NewStartDemo\NetworkDemo\NetworkDemo
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)
#TARGET_CPU_ABI := armeabi
#TARGET_CPU_ABI := armeabi-v7a
#TARGET_CPU_ABI := armeabi-v7a-hard
#TARGET_CPU_ABI := armeabi
#设置c++11头文件路径和链接路径
#prebuilt_stdcxx_PATH := E:\android-ndk-r9d-windows-x86_64\android-ndk-r9d\sources\cxx-stl\gnu-libstdc++\4.8
#LOCAL_C_INCLUDES += \
$(prebuilt_stdcxx_PATH)/include \
$(prebuilt_stdcxx_PATH)/libs/$(TARGET_CPU_ABI)/include
#LOCAL_LDFLAGS += -L$(prebuilt_stdcxx_PATH)/libs/$(TARGET_CPU_ABI) -lgnustl_static -lsupc++
LOCAL_MODULE := gamenet_static
LOCAL_MODULE_FILENAME := libgamenet
AL_CPP_EXTENSION := .cpp
LOCAL_SRC_FILES := $(LOCAL_PATH)/libGameNet/Classes/JackInetAdress.cpp \
$(LOCAL_PATH)/libGameNet/Classes/JackNetDelegate.cpp\
$(LOCAL_PATH)/libGameNet/Classes/JackSocket.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/libGameNet/Classes
LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocosdenshion_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocos_extension_static
# LOCAL_WHOLE_STATIC_LIBRARIES += box2d_static
# LOCAL_WHOLE_STATIC_LIBRARIES += cocosbuilder_static
# LOCAL_WHOLE_STATIC_LIBRARIES += spine_static
# LOCAL_WHOLE_STATIC_LIBRARIES += cocostudio_static
# LOCAL_WHOLE_STATIC_LIBRARIES += cocos_network_static
# LOCAL_WHOLE_STATIC_LIBRARIES += cocos_extension_static
LOCAL_WHOLE_STATIC_LIBRARIES += protobuf_static
LOCAL_STATIC_LIBRARIES := lib_game_net
include $(BUILD_STATIC_LIBRARY)
$(call import-module,.)
$(call import-module,audio/android)
# $(call import-module,Box2D)
# $(call import-module,editor-support/cocosbuilder)
# $(call import-module,editor-support/spine)
# $(call import-module,editor-support/cocostudio)
# $(call import-module,network)
# $(call import-module,extensions)
$(call import-module,external/protobuf-2.5.0)
关键点用红色标记出来了,其中BUILD_STATIC_LIBARAY是之前联调失败的关键。当时因为android.mk是复制的networkDemo的android.mk 而应用层 默认是打包成动态链接库(BUILD_SHARED_LIBRARY)的。这导致的问题是libgamenet在运行过程中需要动态加载cocos2d-x的库和 protobuffer的动态库. 之前在联调过程中发现,运行到了libgamenet总会莫名其妙的关闭。找了好久的原因。而且在libgamenet中使用了cocos2d-x的log函数,有一部打印出来 然后马上死掉了。现在想来就是cocos2d-x.so可能没加载。后来修改为BUILD_STATIC_LIBRARY后 就没出现这个问题了。
这是libgamenet中一句打印语句。之前是直接写成log(xxx) 然后就会死在这里。后来我怀疑是cocos2d-x包没加载。将其修改为printf发现就不会死掉。由此确认确实是BUILD_SHARED_LIBARARY的原因。 这里JACKLog是一个宏定义而已。
当时用这个宏来判断是不是log的问题。
c) 可选(使用vs2012+visual gdb构建项目)
这一步是可选项目。Visual gdb支持的。但是后面发现这一步是不需要的。但是可以作为过程了解。
注意事项。
VS2012 + visual GDB调试android
1. Android 使用android打包过程出现很多问题 但是都可以解决。 Crunch 删除就好了
2. Build.xml 698 打开E:\ylss\project\NewStartDemo\NetworkDemo\NetworkDemo\cocos2d\cocos\platform\android\java 下的打开proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
3. 提示 mutle什么的是 cocos2d-x的包重复了。 打开eclipse build_path中去掉重复的src 重新打包就好了
其中3中,在eclipse打包过程中, 添加linksrc是必须的 不然不能打包 而ant构建又不能有 所以看你自己选择的打包工具
在eclipse中,这两个都指向同一个目录。Eclipse打包需要这样才能避免出现找不到cocos2d-x-activtiy is not type之类的错误。 而是用ant打包又不许移除掉一个
d) 这里列出其他配置文件的设置一遍复
开启gdb 方便联调的时候设置断点。完整的build_native.py:
#!/usr/bin/python
# build_native.py
# Build native codes
import sys
import os, os.path
import shutil
from optparse import OptionParser
def check_environment_variables_sdk():
''' Checking the environment ANDROID_SDK_ROOT, which will be used for building
'''
try:
SDK_ROOT = os.environ['ANDROID_SDK_ROOT']
except Exception:
print "ANDROID_SDK_ROOT not defined. Please define ANDROID_SDK_ROOT in your environment"
sys.exit(1)
return SDK_ROOT
def check_environment_variables():
''' Checking the environment NDK_ROOT, which will be used for building
'''
try:
NDK_ROOT = os.environ['NDK_ROOT']
except Exception:
print "NDK_ROOT not defined. Please define NDK_ROOT in your environment"
sys.exit(1)
return NDK_ROOT
def select_toolchain_version():
'''Because ndk-r8e uses gcc4.6 as default. gcc4.6 doesn't support c++11. So we should select gcc4.7 when
using ndk-r8e. But gcc4.7 is removed in ndk-r9, so we should determine whether gcc4.7 exist.
Conclution:
ndk-r8e -> use gcc4.7
ndk-r9 -> use gcc4.8
'''
ndk_root = check_environment_variables()
if os.path.isdir(os.path.join(ndk_root,"toolchains/arm-linux-androideabi-4.8")):
os.environ['NDK_TOOLCHAIN_VERSION'] = '4.8'
print "The Selected NDK toolchain version was 4.8 !"
elif os.path.isdir(os.path.join(ndk_root,"toolchains/arm-linux-androideabi-4.7")):
os.environ['NDK_TOOLCHAIN_VERSION'] = '4.7'
print "The Selected NDK toolchain version was 4.7 !"
else:
print "Couldn't find the gcc toolchain."
exit(1)
def do_build(cocos_root, ndk_root, app_android_root,ndk_build_param,sdk_root,android_platform,build_mode):
ndk_path = os.path.join(ndk_root, "ndk-build")
# windows should use ";" to seperate module paths
platform = sys.platform
if platform == 'win32':
ndk_module_path = 'NDK_MODULE_PATH=%s;%s/external;%s/cocos' % (cocos_root, cocos_root, cocos_root)
else:
ndk_module_path = 'NDK_MODULE_PATH=%s:%s/external:%s/cocos' % (cocos_root, cocos_root, cocos_root)
if ndk_build_param == None:
command = '%s -C %s %s' % (ndk_path, app_android_root, ndk_module_path)
else:
command = '%s -C %s %s %s' % (ndk_path, app_android_root, ''.join(str(e) for e in ndk_build_param), ndk_module_path)
if os.system(command) != 0:
raise Exception("Build dynamic library for project [ " + app_android_root + " ] fails!")
elif android_platform is not None:
sdk_tool_path = os.path.join(sdk_root, "tools/android")
cocoslib_path = os.path.join(cocos_root, "cocos/2d/platform/android/java")
command = '%s update lib-project -t %s -p %s' % (sdk_tool_path,android_platform,cocoslib_path)
if os.system(command) != 0:
raise Exception("update cocos lib-project [ " + cocoslib_path + " ] fails!")
command = '%s update project -t %s -p %s -s' % (sdk_tool_path,android_platform,app_android_root)
if os.system(command) != 0:
raise Exception("update project [ " + app_android_root + " ] fails!")
buildfile_path = os.path.join(app_android_root, "build.xml")
command = 'ant clean %s -f %s -Dsdk.dir=%s' % (build_mode,buildfile_path,sdk_root)
os.system(command)
def copy_files(src, dst):
for item in os.listdir(src):
path = os.path.join(src, item)
# Android can not package the file that ends with ".gz"
if not item.startswith('.') and not item.endswith('.gz') and os.path.isfile(path):
shutil.copy(path, dst)
if os.path.isdir(path):
new_dst = os.path.join(dst, item)
os.mkdir(new_dst)
copy_files(path, new_dst)
def copy_resources(app_android_root):
# remove app_android_root/assets if it exists
assets_dir = os.path.join(app_android_root, "assets")
if os.path.isdir(assets_dir):
shutil.rmtree(assets_dir)
# copy resources
os.mkdir(assets_dir)
resources_dir = os.path.join(app_android_root, "../Resources")
if os.path.isdir(resources_dir):
copy_files(resources_dir, assets_dir)
def build(ndk_build_param,android_platform,build_mode):
ndk_root = check_environment_variables()
sdk_root = None
select_toolchain_version()
current_dir = os.path.dirname(os.path.realpath(__file__))
cocos_root = os.path.join(current_dir, "../cocos2d")
app_android_root = current_dir
copy_resources(app_android_root)
if android_platform is not None:
sdk_root = check_environment_variables_sdk()
if android_platform.isdigit():
android_platform = 'android-'+android_platform
else:
print 'please use vaild android platform'
exit(1)
if build_mode is None:
build_mode = 'debug'
elif build_mode != 'release':
build_mode = 'debug'
#jcracker add
ndk_build_param = 'NDK_DEBUG=1'
do_build(cocos_root, ndk_root, app_android_root,ndk_build_param,sdk_root,android_platform,build_mode)
# -------------- main --------------
if __name__ == '__main__':
parser = OptionParser()
parser.add_option("-n", "--ndk", dest="ndk_build_param", help='parameter for ndk-build')
parser.add_option("-p", "--platform", dest="android_platform",
help='parameter for android-update.Without the parameter,the script just build dynamic library for project. Valid android-platform are:[10|11|12|13|14|15|16|17|18|19]')
parser.add_option("-b", "--build", dest="build_mode",
help='the build mode for java project,debug[default] or release.Get more information,please refer to http://developer.android.com/tools/building/building-cmdline.html')
(opts, args) = parser.parse_args()
build(opts.ndk_build_param,opts.android_platform,opts.build_mode)
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)
LOCAL_MODULE := cocos2dcpp_shared
LOCAL_MODULE_FILENAME := libcocos2dcpp
AL_CPP_EXTENSION := .cc .cpp
#VisualGDBAndroid: AutoUpdateSourcesInNextLine
LOCAL_SRC_FILES := hellocpp/main.cpp
LOCAL_SRC_FILES += ../../Classes/AppDelegate.cpp \
../../Classes/HelloWorldScene.cpp\
../../Classes/TestName.cc
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes
#LOCAL_C_INCLUDES += ../../libGameNet/Classes
LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocosdenshion_static
# LOCAL_WHOLE_STATIC_LIBRARIES += box2d_static
# LOCAL_WHOLE_STATIC_LIBRARIES += cocosbuilder_static
# LOCAL_WHOLE_STATIC_LIBRARIES += spine_static
# LOCAL_WHOLE_STATIC_LIBRARIES += cocostudio_static
# LOCAL_WHOLE_STATIC_LIBRARIES += cocos_network_static
# LOCAL_WHOLE_STATIC_LIBRARIES += cocos_extension_static
LOCAL_WHOLE_STATIC_LIBRARIES += gamenet_static
include $(BUILD_SHARED_LIBRARY)
$(call import-module,.)
$(call import-module,audio/android)
# $(call import-module,Box2D)
# $(call import-module,editor-support/cocosbuilder)
# $(call import-module,editor-support/spine)
# $(call import-module,editor-support/cocostudio)
# $(call import-module,network)
# $(call import-module,extensions)
$(call import-module,../libGameNet/proj.android/jni)
Application.mk:
APP_STL := gnustl_static
NDK_TOOLCHAIN_VERSION := 4.8 #4.8好像不能显示变量 下次尝试一下4.6
APP_CPPFLAGS := -frtti -DCC_ENABLE_CHIPMUNK_INTEGRATION=1 -DCOCOS2D_DEBUG=1 -std=c++11 -fsigned-char
APP_PLATFORM := android-16
APP_OPTIM := debug
APP_ABI := armeabi armeabi-v7a
LOCAL_C_FLAGS += -gdwarf-3
下一篇: