I have a an app whose Main activity shows a GLSurfaceView
. Every time that a new activity is launched, say for example Settings Activity, the OpenGl surface is destroyed, 开发者_如何学Goand a new one is created when the user returns to the main activity.
This is VERY slow, as I need to regenerate textures each time so that they can be bound to the new Surface. (Caching the textures is possible, but it would be my second choice, because of limited availability of memory.)
Is there a way to prevent the Surface being recreated every time?
My own analysis by looking at the code is:
There are two triggers for the Surface to be destroyed:
GLSurfaceView.onPause()
is called by the activity- The view gets detached from the window
Is there a way to prevent #2 from happening when launching a new activity?
If you're targeting 3.0 or later, take a look at GLSurfaceView.setPreserveEGLContextOnPause()
. Keep in mind that devices might still support only one OpenGL context at a time, so if you're switching to another activity that uses OpenGL and back to yours, you will have to reupload anyway – so I'd recommend keeping a cache and dropping it when your Activity's onLowMemory()
is called.
Caching the textures is possible, by it would be my second choice, because of limited availability of memory
If there's a lot of textures, the only solution is to cache them AFAIK, there's no way to keep the surface and textures alive across activity restart. By the way, you can use a lot more memory in native code than in Java.
There has been a long discussion about this on android-ndk. Especially, I posted some benchmarks, which show that bitmap decoding can take up to 85% of texture loading time, texImage2D taking only the remaining 15%.
So caching decoded image data is likely to be a great performance booster, and by coupling this with memory mapped files (mmap), you may even cache a real lot of image data while staying memory-friendly.
Short answer: No
Long Answer: You could cache/save all the textures when you get OnPause(), and restore them at OnResume(). But otherwise the android Activity lifecycle demands the view to be restored from scratch onResume()
From activity cycle
If an activity is paused or stopped, the system can drop the activity from memory by either asking it to finish, or simply killing its process. When it is displayed again to the user, it must be completely restarted and restored to its previous state.
One way to get around it thought is that if you are within you own Application, instead of starting a new activity, create a Overlay/Dialog over the current activity and put the SettingsView in there.
精彩评论