引擎解决将CocosCreator嵌入Android中,第二次打开Cocos会崩溃的问题

需求:在App中嵌入Cocos引擎,点击按钮可以打开Cocos游戏页面。问题在于,第一次打开Cocos,关闭,再次打开Cocos,崩溃。

昨天拿到这个需求,第一反应是不要从引擎上下手,看看是否能从Native上想想办法。比如开一个新进程,专门放CocosActivity这样,但这样只能显示一个,一个出来会盖住另一个。我们的产品需要Cocos变成一个View,和原生Activity一起显示,这就没办法了。

解决思路:

1. 第二次打开游戏崩溃,引擎源码中没有第一次第二次这个概念,每次打开都是新的。所以,不要再第二次那个点上下功夫,把工作重点放在第一次关闭的时候要清理干净这件事上;

2. 观察Cocos启动的时候都要加载些什么,在第一次关闭的时候释放掉;

3. 根据报错日志进行调试。

具体修改(CocosCreator2.4.2):

CCDirector.js的mainLoop方法中:

图1

renderer/index.js中,clear方法改成下面这样:

_userWebGL代表是否使用WebGL

其中userWebGL变量用来记录引擎用了哪个gl:

图1中的两个jsb的方法,是从C++代码中绑定出来的,以便在Director中调用,随便怎么绑定都可以,露出来就行,我的代码如下:

在jsb_global.cpp中:

这两个函数的实现,也在这个类里:

当然,这里enginCleanUp方法要delete引擎核心,但ScriptEngine的析构函数是个私有的,会报错,这里把他改成public的:

选择改哪个文件的时候要注意,选自己的项目会用到的那个改就行。另外有一些在.cache目录下的,都是临时生成的缓存文件,别改那个,改引擎里的。另外如果你改了引擎的代码,他有可能不生效,你需要先关闭cocos,删除.cache目录,打开cocos,构建、编译,这样才能把新改的js和C++代码弄生效。

下图中,我们选择V8目录下的那个,其他的我用不上就没改。

私有变公有:

对了,退出cocos一定要用cc.director.end(),他会把那个purgeDirectorInNextLoop变量设为true,我们的清理逻辑就能进去了。

还有图1调用的原生方法finishSelf,里面就一句代码,就是调用cocosActivity的finish()。

差不多了,可能有一些疏漏,主要是看下流程,然后自己去实现吧,感觉改改引擎还是很有提升的。