安卓平台 加shader,切到后台,再切回来后坐标错乱

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
end

local 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;
    }
    // 正常启动流程
1赞