Cocos Creator3.7.4版本升级16KB分享

Android项目

1、更新gradle及相关插件

gradle:9.0.0
agp version:8.10.0
NDK version:28.2.13676358
Android Stuido:2024.3.2 Patch 1【如果使用更高版本,需要是2025.1.3及以上

2、运行项目,解决提升gradle和NDK后产生的报错

(1)‘unary_function’ in namespace ‘std’; did you mean ‘__unary_function’?

解决方案:
对应版本引擎目录 resources\resources\3d\engine\native 路径下的CMakeLists.txt中 在85行左右新增

if(NOT WINDOWS)
    add_definitions(-DBOOST_NO_CXX98_FUNCTION_BASE)
endif()

(2)xxteaKey相关报错

解决方案:

static std::basic_string<unsigned char> xxteaKey;

static ccstd::string xxteaKey;
static_cast

reinterpret_cast

(3)ALooper_pollAll 报错

解决方案:

ALooper_pollOnce

到此,安卓项目成功更新Gradle和NDK,应该能够构建并成功运行!!!

引擎项目

3、修改引擎,替换android目录

下载cocos-engine-external-3.8.7-16k项目压缩包,
地址:https://github.com/cocos/cocos-engine-external/tree/v3.8.7-16k
将压缩包内的andoroid目录整体替换进引擎的android目录。(Resources/resources/3d/engine/native/external/android)

开始解决报错:

(1)ThrowError相关

解决方案:
修改 resources\resources\3d\engine-native\cocos\bindings\jswrapper\v8\debugger\env.h

  • 390行附近
// inline void ThrowError(v8::Local<v8::Value> (*fun)(v8::Local<v8::String>),
    //                        const char *errmsg);
inline void ThrowError(v8::Local<v8::Value> (*fun)(v8::Local<v8::String>, v8::Local<v8::Value>), const char*errmsg);
  • 538行附近
inline void Environment::ThrowError(
    //v8::Local<v8::Value> (*fun)(v8::Local<v8::String>),
    v8::Local<v8::Value> (*fun)(v8::Local<v8::String>, v8::Local<v8::Value> options),
    const char *errmsg) {
    v8::HandleScope handle_scope(isolate());
    //isolate()->ThrowException(fun(OneByteString(isolate(), errmsg)));
    isolate()->ThrowException(fun(OneByteString(isolate(), errmsg, strlen(errmsg)), {}));

}

(2)session_= inspector->connect(1, this, StringView())

解决方案:
修改resources\resources\3d\engine-native\cocos\bindings\jswrapper\v8\debugger\inspector_agent.cpp

  • 390行附近
//session_ = inspector->connect(1, this, StringView());
# if V8_MAJOR_VERSION > 10 || (V8_MAJOR_VERSION == 10 && V8_MINOR_VERSION > 3)
    session_= inspector->connect(1, this, StringView(), v8_inspector::V8Inspector::ClientTrustLevel::kFullyTrusted);
# else
    session_ = inspector->connect(1, this, StringView());
# endif

(3)ShutdownPlatform

解决方案:
修改resources\resources\3d\engine-native\cocos\bindings\jswrapper\v8\ScriptEngine.cpp

  • 225行附近
//v8::V8::ShutdownPlatform();
#if V8_MAJOR_VERSION > 9 || (V8_MAJOR_VERSION == 9 && V8_MINOR_VERSION > 7)
        v8::V8::DisposePlatform();
#else
        v8::V8::ShutdownPlatform();
#endif
delete platform;

(4)onOOMErrorCallback

解决方案:
修改resources\resources\3d\engine-native\cocos\bindings\jswrapper\v8\ScriptEngine.cpp

  • 265行附近
void ScriptEngine::onOOMErrorCallback(const char *location,
    #if V8_MAJOR_VERSION > 10 || (V8_MAJOR_VERSION == 10 && V8_MINOR_VERSION > 4)
                                      const v8::OOMDetails &details
    #else
                                      bool isHeapOom
    #endif
) {
    ccstd::string errorStr = "[OOM ERROR] location: ";
    errorStr += location;
    ccstd::string message;
    message = "is heap out of memory: ";
    #if V8_MAJOR_VERSION > 10 || (V8_MAJOR_VERSION == 10 && V8_MINOR_VERSION > 4)
    if (details.is_heap_oom) {
    #else
    if (isHeapOom) {
    #endif
        message += "true";
    } else {
        message += "false";
    }

    errorStr += ", " + message;
    SE_LOGE("%s\n", errorStr.c_str());
    getInstance()->callExceptionCallback(location, message.c_str(), "(no stack information)");
}
  • 855行附近
//v8::ScriptOrigin origin(_isolate, originStr.ToLocalChecked());
    v8::ScriptOrigin origin(originStr.ToLocalChecked());
  • 945行附近
//v8::ScriptOrigin origin(_isolate, scriptPath);
    v8::ScriptOrigin const origin(scriptPath);
  • 1009行附近
// v8::ScriptOrigin origin(_isolate, scriptPath, 0, 0, true);
    v8::ScriptOrigin const origin(scriptPath, 0, 0, true);

修改resources\resources\3d\engine-native\cocos\bindings\jswrapper\v8\ScriptEngine.h

  • 367行附近
//static void onOOMErrorCallback(const char *location, bool isHeapOom);
    static void onOOMErrorCallback(const char *location,
    #if V8_MAJOR_VERSION > 10 || (V8_MAJOR_VERSION == 10 && V8_MINOR_VERSION > 4)
                                   const v8::OOMDetails &details
    #else
                                   bool isHeapOom
    #endif
    );

5、Node.cpp

修改Resources/resources/3d/engine-native/cocos/core/scene-graph/Node.cpp

  • 59行附近
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winvalid-offsetof"
#endif
    static_assert(offsetof(Node, _finalOpacity) + sizeof(_finalOpacity) - offsetof(Node, _eventMask) == NODE_SHARED_MEMORY_BYTE_LENGTH, "Wrong shared memory size");
#ifdef __clang__
#pragma clang diagnostic pop
#endif
    _sharedMemoryActor.initialize(&_eventMask, NODE_SHARED_MEMORY_BYTE_LENGTH);
#undef NODE_SHARED_MEMORY_BYTE_LENGTH

6、JniCocosSurfaceView.cpp

修改Resources/resources/3d/engine-native/cocos/platform/android/jni/JniCocosSurfaceView.cpp

  • 222行附近
// int size = env->GetArrayLength(ids);
// jint id[size];
// jfloat x[size];
// jfloat y[size];

// env->GetIntArrayRegion(ids, 0, size, id);
// env->GetFloatArrayRegion(xs, 0, size, x);
// env->GetFloatArrayRegion(ys, 0, size, y);
const int size = env->GetArrayLength(ids);
std::vector<jint> id(size);
std::vector<jfloat> x(size);
std::vector<jfloat> y(size);

env->GetIntArrayRegion(ids, 0, size, id.data());
env->GetFloatArrayRegion(xs, 0, size, x.data());
env->GetFloatArrayRegion(ys, 0, size, y.data());
  • 248行附近
// int size = env->GetArrayLength(ids);
// jint id[size];
// jfloat x[size];
// jfloat y[size];

// env->GetIntArrayRegion(ids, 0, size, id);
// env->GetFloatArrayRegion(xs, 0, size, x);
// env->GetFloatArrayRegion(ys, 0, size, y);
const int size = env->GetArrayLength(ids);
std::vector<jint> id(size);
std::vector<jfloat> x(size);
std::vector<jfloat> y(size);

env->GetIntArrayRegion(ids, 0, size, id.data());
env->GetFloatArrayRegion(xs, 0, size, x.data());
env->GetFloatArrayRegion(ys, 0, size, y.data());

7、 android.ts

修改Resources/resources/3d/engine/scripts/native-pack-tool/source/platforms/android.ts

  • 23行附近
javaHome: string;
javaPath: string;
androidInstant: boolean,
isSoFileCompressed: boolean;
maxAspectRatio: string;
remoteUrl?: string;
apiLevel: number;
  • 365行附近
content = content.replace(/PROP_ENABLE_COMPRESS_SO=.*/, `PROP_ENABLE_COMPRESS_SO=${options.isSoFileCompressed ? "true" : "false"}`);


const ndkPropertiesPath = cchelper.join(options.ndkPath, 'source.properties');
if (fs.existsSync(ndkPropertiesPath)) {
    const ndkContent = fs.readFileSync(ndkPropertiesPath, 'utf-8');
    const regexp = new RegExp(`Pkg.Revision = (.*)`);
    const r = ndkContent.match(regexp);
    if (r) {
        content = content.replace(/PROP_NDK_VERSION=.*/, `PROP_NDK_VERSION=${r[1]}`);
    }
}
  • 371行附近 注释下面代码
//content = content.replace(/PROP_NDK_PATH=.*/, `PROP_NDK_PATH=${options.ndkPath}`);

8、CMakeLists.txt

修改项目/proj/native/engine/android/CMakeLists.txt


#cc_android_after_target(${CC_LIB_NAME})

# 开启16KB

if(ANDROID)

target_link_options(${CC_LIB_NAME} PRIVATE "-Wl,-z,max-page-size=16384")

endif()

cc_android_after_target(${CC_LIB_NAME})

测试运行

3赞

六六六
给乐意分享的点个赞

哥们替换的是

这个路径下的android?

有V8目录的那个android目录


对应位置替换

哥们谢啦!!!

哥们第7这一点对不上

Resources/resources/3d/engine/scripts/native-pack-tool/source/platforms/android.ts
只有第一个25行左右的稍微能对上,后面两个完全对不上

365 和371的 对不上 371要注释的我大概是在220左右找到的

哥们还有一个问题请教一下。v8的.a复制过来,v8相关的就都不需要手动编译了?引擎改动了不需要重新build?

能找到类似位置就好。

引擎的源码相关,我的理解是在android工程build的时候会处理的,我们开发者也只是在android项目里面建立起对引擎模块的引用。

哥们 static_cast 改 reinterpret_cast 是当前版本的引擎下的?我(C:\ProgramData\cocos\editors\Creator\3.7.4\resources\resources\3d\engine 这个路径下)搜索起来2w多个涵盖了.h .cpp .hpp .mm等类型文件

去运行android项目,哪里报错按照指南改哪里,不要这样子直接搜代码改。
先要保证升级打包工具和gradle版本后项目依然能成功运行,
然后再去修改引擎相关的内容。

环境和你一样的话build成功编译apk 就是差这个 xxteaKey相关报错。其他都能过,如果改用尝试ndk26编译C++,发现打包apk 成功但是发现resoures.arsc 是No


查了一下谷■的文档也是建议ndk r28或者以上

哥们你意思是androidStudio 显示哪里 xxteaKey报错 改哪里,不能直接全改?


嗯,不用全部改,再就是,ndk不要用低的了。

哥们 我这边全按你的配置也是不行。。。编译,生成apk全通过的, 但是用 androidStudio的 analyze apk发现还是不支持 还是resoures.arsc 是No

gradle-9.0.0-all.zip
classpath ‘com.android.tools.build:gradle:8.10.0’


还是不行