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 内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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 中继续输入如下命令

1
./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
填写的内容为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#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);
}

使用方法为

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

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

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

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

发表评论

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