Ejecutar una tarea larga en glThread sin bloquear el hilo de la interfaz de usuario en Android

Tengo que ejecutar a través de una gran cantidad de inicialización antes de poder hacer cualquier cosa en mi GLSurfaceView

Las tesis se deben hacer en el hilo de OpenGL.

Sin embargo, esto cuelga mi hilo principal durante la duración de la inicialización.

Aquí está mi código:

 @Override protected void onStart() { super.onStart(); FrameLayout renderingLayout = (FrameLayout) findViewById(R.id.movie_rendering_layout); if (renderingLayout != null && mGLView == null) { mGLView = new MyGLSurfaceView(getApplicationContext()); /** [..] **/ renderingLayout.addView(mGLView, params); } } /*--------------- OPENGL RELATED ---------------*/ protected class MyGLSurfaceView extends GLSurfaceView { private final MyGLRenderer mRenderer; public MyGLSurfaceView(Context context) { super(context); // Create an OpenGL ES 1.0 context setEGLContextClientVersion(1); mRenderer = new MyGLRenderer(); // Set the Renderer for drawing on the GLSurfaceView setRenderer(mRenderer); } } protected class MyGLRenderer implements GLSurfaceView.Renderer { private int mWidth, mHeight = 0; private boolean isFinished = false; public void onSurfaceCreated(GL10 unused, EGLConfig config) { // Set the background frame color GLES10.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); init(mMovieIndex, AssetsUtils.getBinPath(getApplicationContext())); // <----- THIS takes long time } public void onDrawFrame(GL10 pGL10) { GLES10.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); GLES10.glClear(GLES10.GL_COLOR_BUFFER_BIT); /* [...] */ } 

La respuesta habitual es crear dos contextos EGL en el mismo grupo compartido, cada uno vinculado a un subproceso independiente.

El hilo principal en el bucle de renderizado hace cualquier renderizado a pantalla, que durante la carga de recursos es normalmente algo "aburrido" – es decir, un gráfico de carga, una barra de progreso, etc.

El segundo subproceso carga todos los recursos masivos en el fondo, por ejemplo, cargando archivos de textura, mallas de modelo, etc. y subiendo los mismos.

Una vez finalizada la carga, el hilo principal puede utilizar todos los recursos de datos cargados por el hilo secundario de carga asíncrona.

He encontrado una solución:

El problema es que no debe bloquear en onDrawFrame o onSurfaceCreated , ya que son llamados sincrónicamente por el subproceso principal.

Para desactivar las llamadas, he utilizado en mi superficie constructor:

 setRenderMode(RENDERMODE_WHEN_DIRTY); 

De esta forma, las llamadas a onDrawFrame se detendrán una vez que se haya resuelto la vista.

He realizado la inicialización desde

 public void onWindowFocusChanged(boolean hasFocus) 

Tenga cuidado de que se puede llamar dos veces. Si alguien tiene una mejor sugerencia que yo con mucho gusto escucharlo (tomado de ¿Cómo hacer una devolución de llamada después de la vista es completamente prestados? )

Yo también anulado

 @Override public boolean isDirty() return false; } 

Y no olvide usar queueEvent para ejecutar código en el GLThread

  • SurfaceView se retrasa si está en ScrollView
  • Adición de vista de texto a la vista de superficie
  • Android: problema SurfaceView (anchura, altura)
  • Ocultar una vista de superficie que se superpone a otra
  • Cómo reproducir varios archivos de video simultáneamente en un diseño lado a lado en diferentes vistas en Android
  • Android SurfaceView no muestra onDraw
  • Cómo crear y guardar una captura de pantalla desde una vista de superficie?
  • Android SurfaceView onDraw Pregunta
  • Reinicio / Pausa del hilo en onResume / onPause
  • Cómo capturar la imagen de CameraView personalizado en Android?
  • El video de la API de MediaCodec de Android se reproduce demasiado rápido
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.