rt 请问大家是怎么解决这个问题的呢
是什么版本的?有用studio吗?能提供个重现的Demo吗?
3.2 ui用的cocostudio 这个貌似很多人有遇到 原因大概是切后台以后着色器重置了 而只有cocos2dx的默认内置shader被reload了(GLProgramCache::reloadDefaultGLPrograms)这个reload在javaactivity.cpp里面的Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit里面调用的 但是自定义shader没有被reload 网上查到的解决方案是比较蛋疼的写法 把shader定义在C++层 自定义shader和default shader写一起 就是写死了 不知道有没有其他的解决方案
这问题到现在一直到3.17都还有吧,谁有比较好的解决方案了吗,求分享
ps:一般正常情况下来回切后台,系统不会自动释放安卓Activity,只在内存不足时等特殊情况才会触发,所以一般发现不了,要测试切后台问题可以打开:开发者模式->应用->不保留(用户离开后即销毁每个活动)
这样每次切后台都会触发AppActivity重建,再结合楼上描述的代码内容,如果你有使用自定义shader的,都会测试到异常了。
分享下自己改的代码:
重载一下相关的函数:cc.GLProgram.createWithFilenames与cc.GLProgramCache:getInstance().addGLProgram,
在引擎内置event_renderer_recreated事件中重新加载shader即可,参考代码如下:
– android在切后台回来后,系统可能释放了资源(内存不足或开发者模式->应用->不保留(用户离开后即销毁每个活动)等模式下)
– 自定义的shader需自己监听回调重载
local createWithFilenames = cc.GLProgram.createWithFilenames
function cc.GLProgram:createWithFilenames(vShaderFilename, fShaderFilename)
local p = createWithFilenames(self,vShaderFilename,fShaderFilename)
p.vShaderFilename = vShaderFilename
p.fShaderFilename = fShaderFilename
return p
endlocal addGLProgram = cc.GLProgramCache:getInstance().addGLProgram function cc.GLProgramCache:addGLProgram(program,programname) --监听javaactivity-android.cpp抛出的事件:#define EVENT_RENDERER_RECREATED "event_renderer_recreated" local eventDispatcher = cc.Director:getInstance():getEventDispatcher() local e_r_r = cc.EventListenerCustom:create("event_renderer_recreated",function(parameters) local program = cc.GLProgramCache:getInstance():getGLProgram(programname) if program.vShaderFilename and program.fShaderFilename then -- 重新加载绑定shader print("重新加载绑定shader:",programname) program:reset() program:initWithFilenames(program.vShaderFilename, program.fShaderFilename) program:bindAttribLocation(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION) program:bindAttribLocation(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR) program:bindAttribLocation(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS) program:link() program:updateUniforms() end end) eventDispatcher:addEventListenerWithFixedPriority(e_r_r,1) return addGLProgram(self,program,programname) end -----------------------------------
我有个比较好的解决方案,就是当活动被销毁,然后重建的时候直接重启整个应用程序,然后就不用考虑活动被销毁的问题了。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) { // 非正常启动流程,直接从新初始化应用界面
Log.i("FYD:", "restart app");
finish();
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
android.os.Process.killProcess(android.os.Process.myPid());
return;
}
// 正常启动流程