Android-GlSurfaceView在Fragment中同时运行了两次

Android-GlSurfaceView在Fragment中同时运行了两次,android,android-layout,android-fragments,kotlin,opengl-es,Android,Android Layout,Android Fragments,Kotlin,Opengl Es,我有一个android应用程序,它使用GlSurfaceView在片段中渲染3D全屏场景。我在探查器中注意到,GlSurfaceView实际上运行了两次(在两个线程中),占用资源并存储FPS。我通过将相同的OpenGL场景(使用相同的渲染器实现)渲染到实时墙纸并对其进行分析(只运行一次)确认了这个问题 我做错什么了吗 代码如下: MySurfaceView class MySurfaceView(ctx: Context): GLSurfaceView(ctx) { init

我有一个android应用程序,它使用
GlSurfaceView
在片段中渲染3D全屏场景。我在探查器中注意到,
GlSurfaceView
实际上运行了两次(在两个线程中),占用资源并存储FPS。我通过将相同的OpenGL场景(使用相同的
渲染器
实现)渲染到实时墙纸并对其进行分析(只运行一次)确认了这个问题

我做错什么了吗


代码如下:

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
    }
}
main活动

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()
片段(使用您的代码不会使用
此.activity
编译)

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)
    }
}
下面是profiler屏幕截图:

因此,要概括地将
添加
替换为
替换
,请将
此活动
替换为
requirereactive()
requirereactive()
也不会返回空值,并且保证返回空值


希望对你有帮助

有几件事你应该检查一下:

  • 在GLSurfaceView的生命周期中,您只能调用一次
    setRenderer
    。看
  • 如果视图在后台,是否调用
    glView.onPause()
    glView.onResume()
    停止渲染?看
  • 您应该使用
    transaction.replace()
    而不是
    transaction.add()
    。您可能会同时激活多个
    OpenGlFragments

您确定这一行:MySurfaceView(this.activity),可能是新的MySurfaceView(this.activity)。@nikola lukic这是kotlin,它没有
新的
。除了重复片段的问题,代码还在工作。你的布局中有什么?一个可能的原因是,如果您的布局文件已经包含一个
OpenGLFragment
,然后您在
onCreate()
中添加了第二个,是否因为您将
Fragment
添加到backbackbackback(可能的原因)?只要试着替换
FragmentManager
中的
Fragment
。@jeelvankhee这到底是怎么回事?目前,每次我切换到另一个应用程序并返回到此应用程序时,它都会重新启动。那很好,但是我可以让碎片从后面跑吗?谢谢。我猜我没有使用onPause等是为什么当我将应用程序切换到后台然后返回时,OpenGL状态总是被重新创建的原因?我如何阻止这种情况发生?
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)
    }
}