fru*_*mle 9 lifecycle android opengl-es glsurfaceview
我GLSurfaceView在我的应用程序中使用,最近在调整它的大小时发现了一个奇怪的行为。最后,我找出了导致我的应用程序出现问题的原因,并创建了一个简单的示例来重现它。
假设我们有一个FrameLayout包含 simple GLSurfaceView. 在每次点击时,GLSurfaceView我们使用以下代码更改其高度
CyclicIterator<Integer> iterator = CyclicIterator.from(200, 300, 500);
glView.setOnClickListener(v -> {
glView.getLayoutParams().height = sizeIterator.next();
glView.requestLayout();
});
Run Code Online (Sandbox Code Playgroud)
一切顺利,直到我们在后台快速移动应用程序,然后使用“概览”按钮(类似于“猴子测试”)返回到前台。如果我们足够快地在背景/前景之间切换并再次调整视图大小,我们最终可能会遇到以下情况:表面内出现一个“死”区域,直到我们再次停止/开始活动它才会更新。
我glGetError在每次 gl 调用后都检查过,没有收到任何错误。同时我收到了正确的width和height在onSurfaceChanged回调。
我尝试重现此行为并在 Nexus 5X 和小米红米 6A 上获得相同的结果。
GLSurfaceView 配置为:
glView.setEGLContextClientVersion(2);
glView.setRenderer(new Renderer() {
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
}
@Override
public void onDrawFrame(GL10 gl) {
gl.glClear(GLES20.GL_COLOR_BUFFER_BIT);
}
});
glView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
Run Code Online (Sandbox Code Playgroud)
正如官方文档所说,我们应该通知GLSurfaceView生命周期事件:
@Override
protected void onStart() {
super.onStart();
glView.onResume();
}
@Override
protected void onStop() {
glView.onPause();
super.onStop();
}
Run Code Online (Sandbox Code Playgroud)
然而,在实际应用中,当我们的应用进入后台时,我们还需要保存首选项并释放一些资源和服务(参见 Google 的相机示例)。正如我发现的,正是这些调用导致了GLSurfaceView我的应用程序中的故障,所以我通过以下方式模拟了它们:
@Override
protected void onResume() {
super.onResume();
// Simulate such actions as e.g.:
// restorePreferences();
// startCameraThread();
// openCamera();
synchronized (this){
try{
this.wait(400);
}catch (InterruptedException ie){
ie.printStackTrace();
}
}
}
@Override
protected void onPause() {
// Simulate such actions as e.g.:
// releaseCamera();
// stopCameraThread();
// savePreferences();
synchronized (this){
try{
this.wait(400);
}catch (InterruptedException ie){
ie.printStackTrace();
}
}
super.onPause();
}
Run Code Online (Sandbox Code Playgroud)
我发现可以通过将GLSurfaceView的可见性切换到GONE和返回VISIBLEin来修复此故障onResume。
@Override
protected void onResume() {
super.onResume();
//...
glView.setVisibility(View.GONE);
glView.setVisibility(View.VISIBLE);
//...
}
Run Code Online (Sandbox Code Playgroud)
但是,这显然不是我正在寻找的解决方案,所以
我是否错过了一些重要的工作GLSurfaceView,或者它只是其实现中的一个错误?
| 归档时间: |
|
| 查看次数: |
85 次 |
| 最近记录: |