SurfaceView/VideoView

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SurfaceView/VideoView相关的知识,希望对你有一定的参考价值。

参考技术A 我们经常用SurfaceView和VideoView来播放视频,但是这两个东东,经常都会出问题。

①SurfaceView不会添加到View树上,并且显示在所有View之上
②在按Home键的时候,会让Surface销毁,并且在重新进入APP的时候,让Surface重建,在Surface重建的时候,SurfaceView那一块是透明的,显示的会是Activity的背景
③如果是列表中的子view中播放视频,在上下滑动的时候,会导致Surface绘制不及时,会有残留
④多个VideoView同时播放的时候,在SurfaceFlinger支持不好的手机上,会出现下一个SurfaceView的某一帧会显示在上一个SurfaceView上

①VideoView是直接继承SurfaceView
②VideoView中的openVideo可能会ANR
③VideoView中的release,stopPlayBack都会导致ANR,因为这些方法都是同步执行的,并且通过IPC服务交给MediaServer去释放资源
解决方法:
使用TextureView替换SurfaceView实现VideoView,因为TextureView是直接继承View的,并且在ListView中滑动的时候,也不会在滑动的时候,有帧残留

当我们有一个列表,每个子项就是一个视频,并且自动播放。surfaceView使用的就是android自带的状态机来控制播放,所以就会一段一段的将视频先读到缓冲区,再播放。由于MediaPlayer中的release,reset,stopPlayBack都是同步的。而且当视频卡片在滑出屏幕之后,需要把视频暂停,在不可见的时候不进行播放。节省系统资源,并且节省用户流量。而如果同时出现多个视频的时候,会频繁调用到上述生命周期方法,导致很容易出现ANR。
解决方法:
问题1.在视频划出ListView的时候,停止播放视频。
解决方案:在ListView中调用setRecycleListener,设置View回收的监听,因为ListView的重用性,会在View回收到scrap区的时候,通过这个Listener进行一些处理,所以在这里根据View.getTag,找到视频View的引用,调用stopPlayBack停止

问题2.频繁调用release等方法导致ANR
解决方案:在视频调用的时候,建立一个释放视频资源的守护线程。在Android中,直接可以用HandlerThread,因为这样可以尽可能的让资源的消耗达到最少,HandlerThread在没有新事件到来的时候,都是处于wait状态,直到有新事件的到来,才会被notify,处理新事件。它里面也是通过一个Thread,在这个Thread中新建一个Looper,在Looper中没有事件的话,则wait,一旦通过Handler发送新事件的话,则会被notify。所以会在子线程中加入一个队列,当需要release的MediaPlayer,直接丢到子线程去进行资源释放。
但是这样会导致一个问题,就是Android维护的MediaPlayer的状态机中的状态可能会乱,这时候就会抛出IllegalStateException,目前对于这种异常,我们选择了捕获它。

另外,由于MediaPlayer.setSurface需要传递一个Surface,然后再在这个Surface上进行绘制,如果频繁new Surface传入的话,就会导致GrafficBuffer分配Surface失败,从而MediaPlayer会回调onError中,显示视频不能播放。所以尽可能一个视频View用一个Surface。

Android VideoView 或 SurfaceView 播放视频?

【中文标题】Android VideoView 或 SurfaceView 播放视频?【英文标题】:Android VideoView or SurfaceView to play videos? 【发布时间】:2016-07-21 16:58:55 【问题描述】:

我应该使用哪一个来减轻设备系统和电池的重量,VideoView 还是 SurfaceView?

谢谢

【问题讨论】:

也许你应该问一下是用SurfaceView还是TextureView? 【参考方案1】:

VideoView 使用SurfaceView。在您关注的领域,它们是平等的。

【讨论】:

谢谢CommonsWare。我在谷歌上寻找直接答案,但没有找到任何答案。再次感谢您。 @pskink:是的,但这很复杂。 :-) @CommonsWare 对不起,我的评论是针对 OP,而不是你 ;-)

以上是关于SurfaceView/VideoView的主要内容,如果未能解决你的问题,请参考以下文章

android videoview和surfaceview的区别

android videoview和surfaceview的区别

放置在 SurfaceView 上时,VideoView 在 FrameLayout 中不可见

Android多媒体功能开发——使用VideoView控件播放视频

TextureView/SurfaceView/GLSurfaceView/VideoView渲染视频(点播播放器)

android java中的圆角videoview