@autho mucjgm
版本:cocos2dx3.10
背景:公司需要把游戏整合到一个APP里面。于是打算通过activity切换的方式实现。但是游戏退出重进之后总会出现fatal 11线程报错。于是有了以下修改。我是底层小白。折腾了好久总算鼓捣出一个能用的版本。优化的地方应该有很多。不过就没去好好优化了。
准备步骤
1.java层。
添加activity互相调用。
以及cocos对应的activity的finish调用函数。(提供给C++去调用。由java自己调用在某些机子上会出现释放不正确的bug。导致线程无法释放)
屏蔽底层关闭进程的调用。(集成了只有一个进程。不能关闭)
2.C++层。
添加调用ScriptingCore清除的函数。(每次退出清空js代码)
添加SctiptingCore初始化中关于是否首次进入的初始化。(sc对象重新注册)
在director的mainloop中添加退出操作和判定。(由C++去调用java层的finish。)
3.js层。
退出时调用cc.director.end.(由js发起整个退出)
以下上修改代码。
1.java层。
Cocos2dxHelper.java文件。屏蔽terminateProcess函数内的调用。
Cocos2dxActivity.java文件。添加函数。
public static void selffinish(){
sContext.finish();
}
这里最好别这么干。因为主activity是继承Cocos2dxActivity的。直接在这里finish的话主activity释放不完全。只是一个调用示例。对应的之后改C++层代码。
2.C++层。
frameworks/cocos2d-x/cocos/platform/CCApplicationProtocol.h
添加clearSc函数。virtual void clearSc() = 0;
AppDelegate.h
添加clearSc函数。
virtual void clearSc();
AppDelegate.cpp
实现clearSc
void AppDelegate::clearSc(){
ScriptingCore::getInstance()->cleanup();
}
frameworks/cocos2d-x/cocos/scripting/js-bindings/manual/ScriptingCore.h
添加初始化判定。
bool ifFirst = true;
frameworks/cocos2d-x/cocos/scripting/js-bindings/manual/ScriptingCore.cpp
修改函数。
void ScriptingCore::start()
{
// for now just this
createGlobalContext();
ifFirst = false;
}
在createGlobalContext添加代码
void ScriptingCore::createGlobalContext() {
if (_cx && _rt) {
ScriptingCore::removeAllRoots(_cx);
JS_DestroyContext(_cx);
JS_DestroyRuntime(_rt);
_cx = NULL;
_rt = NULL;
}
// Start the engine. Added in SpiderMonkey v25
if (!JS_Init()){
return;
}
if(!ifFirst){//!!!!!!!ADD THIS 添加这个初始化
initRegister();
}
//...............
}
frameworks/cocos2d-x/cocos/base/CCDirector.cpp
添加include#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "jni/JniHelper.h"
#endif
修改mainloop函数
void DisplayLinkDirector::mainLoop()
{
auto OutJudge = false;
static std::string activity = "org/cocos2dx/lib/Cocos2dxActivity";//此处可以修改为主activity。也可以通过C++调用js去获取activity
static std::string fun = "selffinish";
if (_purgeDirectorInNextLoop)
{
_purgeDirectorInNextLoop = false;
//#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)//这是我自己获取activity和方法的代码。
//activity = Application::getInstance()->getJavaInfo(1);
//fun = Application::getInstance()->getJavaInfo(2);
//CCLOG("CALLING!!!%s, %s",activity.c_str(), fun.c_str());
//#endif
purgeDirector();
Application::getInstance()->clearSc();
OutJudge = true;
}
else if (_restartDirectorInNextLoop)
{
_restartDirectorInNextLoop = false;
restartDirector();
}
else if (! _invalid)
{
drawScene();
// release the objects
PoolManager::getInstance()->getCurrentPool()->clear();
}
if(OutJudge){
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
JniMethodInfo t;
JniHelper::getStaticMethodInfo(t, activity.c_str(), fun.c_str(), "()V");
t.env->CallStaticVoidMethod(t.classID, t.methodID);
#endif
}
}
之后重新编译。就应该可以了。