Android - Fragment 中的 GlSurfaceView 同时是 运行 两次
Android - GlSurfaceView in Fragment is running twice at the same time
我有一个 android 应用程序,它使用 GlSurfaceView
在片段内渲染 3D 全屏场景。我在分析器中注意到,GlSurfaceView
实际上是 运行 两次 (在两个线程中),占用资源并降低 FPS。我已经通过将相同的 OpenGL 场景(使用相同的 Renderer
实现)渲染到动态壁纸并分析它来确认这个问题,它只运行一次。
我是不是做错了什么?
代码如下:
MySurfaceView
class MySurfaceView(ctx: Context): GLSurfaceView(ctx)
{
init
{
setEGLContextClientVersion(3)
preserveEGLContextOnPause = true
setRenderer( /* instantiating the renderer class */ )
}
}
OpenGLFragment
class OpenGLFragment: Fragment()
{
private lateinit var glView: GLSurfaceView
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View?
{
this.glView = MySurfaceView(this.activity)
return this.glView
}
}
MainActivity
class MainActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val fm = supportFragmentManager
for (i in 0 until fm.getBackStackEntryCount()) {
fm.popBackStack()
}
supportFragmentManager.beginTransaction().add(R.id.main_container, OpenGLFragment())
.addToBackStack(null).commit()
}
}
您似乎在尝试添加片段而不是替换容器。
这是我的代码:
supportFragmentManager.beginTransaction()
.replace(R.id.main_container, GLFragment())
.addToBackStack(null)
.commit()
片段(使用您的代码无法通过 this.activity
编译)
class GLFragment : Fragment() {
private lateinit var glView: GLSurfaceView
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
this.glView = MySurfaceView(requireActivity())
return this.glView
}
}
GLView:
class MySurfaceView constructor(context: Context) : GLSurfaceView(context) {
init {
setEGLContextClientVersion(2) // I have used 2 because running on emulator
preserveEGLContextOnPause = true
setRenderer(ClearRenderer())
}
}
internal class ClearRenderer : GLSurfaceView.Renderer {
override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
}
override fun onSurfaceChanged(gl: GL10, w: Int, h: Int) {
gl.glViewport(0, 0, w, h)
}
override fun onDrawFrame(gl: GL10) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT or GL10.GL_DEPTH_BUFFER_BIT)
}
}
这是探查器屏幕截图:
所以总结一下,用replace
替换add
,用requireActivity()
替换this.activity
,requireActivity()
也不return null这是有保证的。
希望对您有所帮助!!!
您应该检查一些事项:
- 您只能在 GLSurfaceView 的生命周期中调用
setRenderer
一次。参见 GLSurfaceView.setRenderer。
- 如果视图在后台,您是否调用
glView.onPause()
和 glView.onResume()
停止渲染?参见 GLSurfaceView life-cycle。
- 您应该使用
transaction.replace()
而不是 transaction.add()
。您最终可能会同时激活多个 OpenGlFragments
。
我有一个 android 应用程序,它使用 GlSurfaceView
在片段内渲染 3D 全屏场景。我在分析器中注意到,GlSurfaceView
实际上是 运行 两次 (在两个线程中),占用资源并降低 FPS。我已经通过将相同的 OpenGL 场景(使用相同的 Renderer
实现)渲染到动态壁纸并分析它来确认这个问题,它只运行一次。
我是不是做错了什么?
代码如下:
MySurfaceView
class MySurfaceView(ctx: Context): GLSurfaceView(ctx)
{
init
{
setEGLContextClientVersion(3)
preserveEGLContextOnPause = true
setRenderer( /* instantiating the renderer class */ )
}
}
OpenGLFragment
class OpenGLFragment: Fragment()
{
private lateinit var glView: GLSurfaceView
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View?
{
this.glView = MySurfaceView(this.activity)
return this.glView
}
}
MainActivity
class MainActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val fm = supportFragmentManager
for (i in 0 until fm.getBackStackEntryCount()) {
fm.popBackStack()
}
supportFragmentManager.beginTransaction().add(R.id.main_container, OpenGLFragment())
.addToBackStack(null).commit()
}
}
您似乎在尝试添加片段而不是替换容器。
这是我的代码:
supportFragmentManager.beginTransaction()
.replace(R.id.main_container, GLFragment())
.addToBackStack(null)
.commit()
片段(使用您的代码无法通过 this.activity
编译)
class GLFragment : Fragment() {
private lateinit var glView: GLSurfaceView
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
this.glView = MySurfaceView(requireActivity())
return this.glView
}
}
GLView:
class MySurfaceView constructor(context: Context) : GLSurfaceView(context) {
init {
setEGLContextClientVersion(2) // I have used 2 because running on emulator
preserveEGLContextOnPause = true
setRenderer(ClearRenderer())
}
}
internal class ClearRenderer : GLSurfaceView.Renderer {
override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
}
override fun onSurfaceChanged(gl: GL10, w: Int, h: Int) {
gl.glViewport(0, 0, w, h)
}
override fun onDrawFrame(gl: GL10) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT or GL10.GL_DEPTH_BUFFER_BIT)
}
}
这是探查器屏幕截图:
所以总结一下,用replace
替换add
,用requireActivity()
替换this.activity
,requireActivity()
也不return null这是有保证的。
希望对您有所帮助!!!
您应该检查一些事项:
- 您只能在 GLSurfaceView 的生命周期中调用
setRenderer
一次。参见 GLSurfaceView.setRenderer。 - 如果视图在后台,您是否调用
glView.onPause()
和glView.onResume()
停止渲染?参见 GLSurfaceView life-cycle。 - 您应该使用
transaction.replace()
而不是transaction.add()
。您最终可能会同时激活多个OpenGlFragments
。