百度上面很多视频播放都是利用MediaPlayer+显示视图(SurfaceView、TextureView)进行本地或者网络视频的播放。那么利用MediaCodec对视频流进行硬解码的小伙伴该如何在不同的控件之间无缝切换呢?是不是TextureView的生命周期很难控制?
TextureView与SurfaceTexture构成了组合关系,可见SurfaceTexture的确是由TextureView给『包办』了。在程序世界中,一个对象被『包办』无非是指:
(1)这个对象什么时候被创建?
(2)这个对象如何被创建?
(3)这个对象的产生带来了哪些变化,或者说程序自从有了它有哪些不同?
(4)这个对象什么时候被销毁?
之所以对SurfaceTexture这个对象要大动笔墨,因为它是整个显示框架的『连接者』。
是不是遇到过在播放视频返回后台再回来,发现TextureView显示视图是一片黑色?监听TextureView的生命周期你会发现,返回后台是调用了销毁方法的。那你就会问销毁之后岂不是有需要重新创建?重新创建会引来更多的问题,解码去也需要重新初始化。所以我们只能另寻他法,下面方法就是无缝切换的核心部分。
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
Log.d(TAG, "onSurfaceTextureDestroyed: ");
mSurfaceTexture = surface;
return false;
}
在销毁方法中我们注意,有一个返回参数。官方的解释如下
Invoked when the specified SurfaceTexture is about to be destroyed. If returns true, no rendering should happen inside the surface texture after this method is invoked. If returns false, the client needs to call release(). Most applications should return true.
大致的意思是如果返回ture,SurfaceTexture会自动销毁,如果返回false,SurfaceTexture不会销毁,需要用户手动调用release()进行销毁。
现在恍然大悟了吧,我们在销毁的时候返回false,并保存SurfaceTexture对象,然后从后台返回界面的时候在onSurfaceTextureAvailable()方法中,调用setSurfaceTexture(mSurfaceTexture)方法,这样就会恢复之前的画面了。
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface,
int width, int height) {
Log.d(TAG, "onSurfaceTextureAvailable: ");
if(mSurfaceTexture!=null){
mTextureView.setSurfaceTexture(mSurfaceTexture);
}
}
使用ItemTouchHelper轻松实现RecyclerView拖拽排序和滑动删除
DEMO传送门
手机扫一扫
移动阅读更方便
你可能感兴趣的文章