android - Android OpenGL:GLSurfaceView.Renderer.onDrawFrame() 在启动时调用了两次
问题描述
我有一个使用 OpenGL 的简单 Android 应用程序(通过GLSurfaceView)。代码如下:
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyGLSurfaceView(this));
}
class MyGLSurfaceView extends GLSurfaceView implements GLSurfaceView.Renderer {
MyGLSurfaceView(Context context) {
super(context);
setEGLContextClientVersion(2); // OpenGL ES 2.0
setRenderer(this); // callbacks go to this class
setRenderMode(RENDERMODE_WHEN_DIRTY); // draw on request
}
public void onSurfaceChanged(GL10 gl, int width, int height) { }
public void onSurfaceCreated(GL10 gl, EGLConfig config) { }
public void onDrawFrame(GL10 gl) {
/* if (startup) do_only_once(); */
try { Thread.sleep(250); } catch (Exception ignored) { }
}
}
}
在应用程序启动时onDrawFrame()(GLSurfaceView.Renderer)大多数时候调用了两次。据我所知,onSurfaceChanged()(GLSurfaceView.Renderer)应该调用onDrawFrame(),但我不明白为什么它会发生多次。
我想计算和绘制一些“背景”对象,应该只做一次。我使用setRenderMode(RENDERMODE_WHEN_DIRTY)。但是onDrawFrame()仍然被调用了几次。我怎样才能让它只被调用一次?这种重复调用的原因是什么?
在每个函数的开头和结尾为这些函数(以及一些默认的Activity回调)添加日志记录将导致下面的输出。活动生命周期似乎工作正常:
// Example of function with Logging:
protected void onCreate(Bundle savedInstanceState) {
Log.d("__DEBUG__", "onCreate() {");
super.onCreate(savedInstanceState);
setContentView(new MyGLSurfaceView(this));
Log.d("__DEBUG__", "onCreate() }");
}
22:12:46.361 __DEBUG__: onCreate() {
22:12:46.376 __DEBUG__: MyGLSurfaceView() {
22:12:46.376 __DEBUG__: MyGLSurfaceView() }
22:12:46.430 __DEBUG__: onCreate() }
22:12:46.431 __DEBUG__: onStart() {
22:12:46.431 __DEBUG__: onStart() }
22:12:46.432 __DEBUG__: onResume() {
22:12:46.433 __DEBUG__: onResume() }
22:12:46.498 __DEBUG__: onSurfaceCreated() {
22:12:46.498 __DEBUG__: onSurfaceCreated() }
22:12:46.498 __DEBUG__: onSurfaceChanged() {
22:12:46.498 __DEBUG__: onSurfaceChanged() }
22:12:46.498 __DEBUG__: onDrawFrame() {
22:12:46.748 __DEBUG__: onDrawFrame() }
22:12:46.754 __DEBUG__: onDrawFrame() {
22:12:47.004 __DEBUG__: onDrawFrame() }
解决方案
我研究了GLSurfaceView的平台代码,发现onDrawFrame()可以触发两次,其中一次在 ctor 中。
我创建了一个带有建议修复的 AOSP 合并请求,可以在此处找到:https ://android-review.googlesource.com/c/platform/frameworks/base/+/858050 。然而,考虑到可能的风险,它被“拒绝”了,因为它不是太重要......
处理这个问题的唯一方法是在onDrawFrame()内部实现带有 switch-case 的简单状态机。需要保持“初始”状态并重绘初始元素(在我的情况下为背景),直到真正的绘制请求到来(第一个请求将状态机切换到“正常”状态)。
推荐阅读
- r - Plotly(R)中关于“标记”的错误消息
- r - 如何合并R中具有不同列名的两个数据集?
- ios - 为什么 UIAccessibilityNotification 不转向正确的论点?
- powershell - 使用 GitHub 包注册表作为 PowerShell 包存储库
- quarkus - Quarkus 异常处理程序
- java - 在 Chrome 中运行 selenium 测试用例时无法从弹出框加载扩展
- node.js - Mongodb服务器选择超时与nginx,nodejs
- docker - 有没有办法查看完整的 Docker 映像继承?
- swift - 是否可以使用 SwiftUI 将键盘上的“返回”键更改为“完成”?
- c# - 用重复的代码重构静态类c#