SurfaceView和MediaCodec搭配使用退到后台黑屏的问题(应用切换等情况)

前几天遇到了一个有关SurfaceView和MediaCodec搭配使用,退到后台黑屏的问题(应用切换等情况)。这里我分享一下个人最后的解决方案,大家如果用到可以参考。

这个问题要么释放或者不释放。我采取的策略是不释放,更换显示的控件。

1、这里的显示控件 SurfaceView更换成TextureView 。 原因就是TextureView 可以控制后面的显示view不销毁。下

面就是代码:

mTextureview = (TextureView) findViewById(R.id.textureview);

mTextureview.setSurfaceTextureListener(this);

实现TextureView.SurfaceTextureListener这个接口。

关键点下面这两个方法:

@Override

public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { presenterControl.SurfaceViewDestroy();

/退到后台让解码线程暂停mediacodec不释放

mSurfaceTexture = surface; return false;// }

我们在销毁的时候返回false,并保存SurfaceTexture对象,然后从后台返回界面的时候在onSurfaceTextureAvailable()方法中,调用setSurfaceTexture(mSurfaceTexture)方法,这样就会恢复之前的画面了。

@Override

public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {

if(mSurfaceTexture != null){ mTextureview.setSurfaceTexture(mSurfaceTexture);// 一定要设置回来

}

presenterControl.SurfaceOnCreate();//MediaCodec的创建以及开始解码(如存在不为空就不创建)

}

生命周期控制: 切换至后台的时候会调用onSurfaceTextureDestroyed,从后台切换回来会调用onSurfaceTextureAvailable。 TextureView的ViewGroup remove TextureView的时候会调用onSurfaceTextureDestroyed方法。相同,TextureView的ViewGroup add TextureView的时候会调用onSurfaceTextureAvailable。这些都是建立在视图可见的基础上,如果视图不可见,add也不会调用onSurfaceTextureAvailable方法,remove也不会调用onSurfaceTextureDestroyed方法。 当TextureView设置为Gone的时候,并不会调用onSurfaceTextureDestroyed方法法。

2、我们要用到的MediaCodec 在configure时候使用的Surface. 则定义一个方法得到:

public Surface getSurface() {

if (mSurface == null){

mSurface = new Surface(mTextureview.getSurfaceTexture()); }

return mSurface; }

3、由于这里我们没有自动的去释放这个SurfaceTexture,所以在页面销毁的时候。一定要onDetachedFromWindow()手动释放。不然SurfaceTexture会报异常退出错误。

@Override
public void onDetachedFromWindow(){ //如果需要一个比较长生命周期的SurfaceTexture,但是一定要在onDetachedFromWindow()方法中做释放操作.
    super.onDetachedFromWindow();
    if (mSurfaceTexture != null)  {
        mSurfaceTexture.release();
        mSurfaceTexture = null;
    }
    if (surface0 != null) {
        surface0.release();
        surface0 = null;
    }
}

4、补充说明,在实践中遇到了项目卡顿的问题。具体的原因是因为surface本质上是一个缓存显示区域,如果没有释放就会导致卡顿。所以在退到后台的过程中需要释放。在生命周期中加入下面的代码。surface.release();

你可能感兴趣的:(Android开发问题解决)