cocos2d-x-2.x APK 打包问题汇总

很久没有发全技术文章了。。。
今天折腾了几个小时,终于编译成功一个复杂的cocos2d-x-2.x 项目了。。其中遇到的坑数都数不过来。

1.资源目录中不能包含中文路径,否则打包失败

2.XML配置表中不能包含全角符号,否则加载失败

3.在部分低端手机上,SpriteSheet 的大小达不到 2048 * 2048 会导致闪退

由于项目使用了rapidxml, 而 rapidxml 又调用了 Boost 所以这里要编译boost的相关库
boost_system 和 boost_iostreams

Boost相关问题

4.Boost的HPP文件,不需要加入 Android.mk 中,这是一个类似于.h文件一样的东西,不需要填

5.Boost的库需要用NDK打包成库
1)下载最新的Boost 1.55 http://iweb.dl.sourceforge.net/project/boost/boost/1.55.0/boost_1_55_0.zip
2)使用cygwin 编译 bootstrap.sh 生成 b2.exe, bjam.exe
3)修改 /tools/build/v2/user-config.jam 内容如下

import os ;

if [ os.name ] = CYGWIN || [ os.name ] = NT {
androidPlatform = windows ;
}
else if [ os.name ] = LINUX {
androidPlatform = linux-x86_64 ;
}
else if [ os.name ] = MACOSX {
androidPlatform = darwin-x86 ;
}

modules.poke : NO_BZIP2 : 1 ;
ANDROID_NDK = ../.. ;
using gcc : android4.6 : $(ANDROID_NDK)/toolchains/arm-linux-androideabi-4.6/prebuilt/$(androidPlatform)/bin/arm-linux-androideabi-g++ :
<archiver>$(ANDROID_NDK)/toolchains/arm-linux-androideabi-4.6/prebuilt/$(androidPlatform)/bin/arm-linux-androideabi-ar
<ranlib>$(ANDROID_NDK)/toolchains/arm-linux-androideabi-4.6/prebuilt/$(androidPlatform)/bin/arm-linux-androideabi-ranlib
<compileflags>--sysroot=$(ANDROID_NDK)/platforms/android-9/arch-arm
<compileflags>-I$(ANDROID_NDK)/sources/cxx-stl/gnu-libstdc++/4.6/include
<compileflags>-I$(ANDROID_NDK)/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi/include
<compileflags>-DNDEBUG
<compileflags>-D__GLIBC__
<compileflags>-DBOOST_FILESYSTEM_VERSION=3
<compileflags>-lstdc++
<compileflags>-lgnustl_shared
<compileflags>-mthumb
<compileflags>-fno-strict-aliasing
<compileflags>-std=gnu++11
<compileflags>-O2
;

4)调用刚才生成的 b2.exe 在cygwin 中继续输入如下命令

./b2 --without-python --without-mpi --without-serialization toolset=gcc-android4.6 link=static runtime-link=static target-os=linux --stagedir=android

5)成功后会在boost根目录生成 android 文件夹,里面的文件为编译后的库

6)为了和cocos2dx的目录结构一致,把这些库文件复制3份,分别在
cocos2dxplatformthird_partyandroidprebuiltlibboostlibsarmeabi
cocos2dxplatformthird_partyandroidprebuiltlibboostlibsarmeabi-v7a
cocos2dxplatformthird_partyandroidprebuiltlibboostlibsx86

7)将Boost 的 文件夹 就是里面有许多 hpp 文件的文件夹拷贝到下面的路径
cocos2dxplatformthird_partyandroidprebuiltlibboostincludeboost

8)创建Boost 的 Android.mk 文件路径
cocos2dxplatformthird_partyandroidprebuiltlibboostAndroid.mk
填写的内容为

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_atomic
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_atomic.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_chrono
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_chrono.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_context
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_context.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_coroutine
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_coroutine.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_date_time
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_date_time.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_exception
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_exception.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_filesystem
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_filesystem.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_graph
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_graph.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_iostreams
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_iostreams.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_log
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_log.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_log_setup
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_log_setup.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_math_c99
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_math_c99.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_math_c99f
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_math_c99f.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_math_c99l
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_math_c99l.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_math_tr1
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_math_tr1.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_math_tr1f
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_math_tr1f.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_math_tr1l
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_math_tr1l.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_prg_exec_monitor
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_prg_exec_monitor.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_program_options
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_program_options.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_random
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_random.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_regex
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_regex.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_serialization
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_serialization.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_signals
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_signals.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_system
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_system.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_test_exec_monitor
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_test_exec_monitor.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_unit_test_framework
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_unit_test_framework.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_thread
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_thread.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_timer
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_timer.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_wave
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_wave.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= boost_wserialization
LOCAL_MODULE_FILENAME := boost
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libboost_wserialization.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

所有模块都在这里,到时候在项目中的 proj.android.jni.Android.mk 中按需添加

9)打开项目中的 proj.android.jni.Android.mk 做如下添加
LOCAL_WHOLE_STATIC_LIBRARIES += boost_system
LOCAL_WHOLE_STATIC_LIBRARIES += boost_iostreams
我只用到这2个库,因此只添加2个
继续添加
$(call import-module,cocos2dx/platform/third_party/android/prebuilt/libboost)
最后编译 proj.android.jni.Android.mk 即可

编码相关问题
之前做的时候,配置表中有许多中文,因此需要unicode 或者 Gb2312 的编码转换。
用到了 WideCharToMultiByte 和 MultiByteToWideChar
由于这2个API 是 windows.h 中的,只能运行在 win32下,因此无法编译到 android 上。

10)在跨平台上,我使用了iconv 来进行编码转换,下载后放到 cocos2dx-x-2.x 根目录下 libiconv
11)修改 proj.android.jni.Android.mk 添加如下
LOCAL_WHOLE_STATIC_LIBRARIES += libiconv_static
$(call import-module,libiconv)
最后编译即可

顺便放一个编码转换类

CodeConverter.h

#pragma once
#include <string>

#include "iconv/iconv.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#pragma comment(lib,"libiconv.lib")
#endif

class CodeConverter {
private:
    iconv_t cd;
public:
    // ¹¹Ôì
    CodeConverter(const char *from_charset,const char *to_charset);
    ~CodeConverter();
    int convert(char *inbuf,int inlen,char *outbuf,int outlen);
    std::string convertToStr(char *inbuf,int inlen);
};

CodeConverter.cpp

#include "CodeConverter.h"
#include <memory.h>

#define CC_OUTLEN 255

CodeConverter::CodeConverter( const char *from_charset,const char *to_charset )
{
    cd = iconv_open(to_charset,from_charset);
}

CodeConverter::~CodeConverter()
{
    iconv_close(cd);
}

// ת»»Êä³ö
int CodeConverter::convert(char *inbuf,int inlen,char *outbuf,int outlen) {
    char **pin = &inbuf;
    char **pout = &outbuf;

    memset(outbuf,0,outlen);
    return iconv(cd,pin,(size_t *)&inlen,pout,(size_t *)&outlen);
}

std::string CodeConverter::convertToStr(char *inbuf,int inlen) {
    char out[CC_OUTLEN];
    int result = this->convert(inbuf,inlen,out,CC_OUTLEN);
    return std::string(out);
}

使用方法为

CodeConverter cc = CodeConverter("utf-8","gb2312");
str = cc.convertToStr((char *)str.data(),strlen((char *)str.data()));

12)使用stof 将字符串转换为float 也会有跨平台问题, 要替换为 atof

13)使屏幕常亮,需要编辑项目的java启动文件,修改函数为如下

    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    }

《cocos2d-x-2.x APK 打包问题汇总》有1个想法

  1. 我是最近接触一个比较大而且复杂的项目,关于打包这块我也是很模糊,希望你能把你打包项目流程发给我,详细一点的比较好。

发表评论

电子邮件地址不会被公开。 必填项已用*标注