先看anr的打印

native: #10 pc 0000050f  /system/framework/x86/boot.oat (Java_android_media_MediaPlayer__1reset__+115)  at android.media.MediaPlayer._reset(Native method)  at android.media.MediaPlayer.reset(MediaPlayer.java:1514)  at android.widget.VideoView.release(VideoView.java:645)  at android.widget.VideoView.openVideo(VideoView.java:327)  at android.widget.VideoView.setVideoURI(VideoView.java:265)  at android.widget.VideoView.setVideoURI(VideoView.java:248)

VideoView中遗留的问题
VideoView是直接继承SurfaceView
VideoView中的openVideo可能会ANR
VideoView中的release,stopPlayBack都会导致ANR,因为这些方法都是同步执行的,并且通过IPC服务交给MediaServer去释放资源

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

解决办法
使用TextureView替换SurfaceView实现VideoView,因为TextureView是直接继承View的,并且在ListView中滑动的时候,也不会在滑动的时候,有残留(看起来像是普通的View绘制和SurfaceView的绘制是两套)

ANR的问题
由于MediaPlayer中的release,reset,stopPlayBack都是同步的。而我们在ListView的每个卡片中,都有可能出现视频,而且需要自动播放,由于没有时间做视频先下载,再播放,所以选择的是Android自带的流播放。会一段一段的将视频先读到缓冲区,再播放。

而且当视频卡片在滑出屏幕之后,需要把视频暂停,在不可见的时候不进行播放。节省系统资源,并且节省用户流量。而如果同时出现多个视频的时候,会频繁调用到上述导致ANR的方法,会很容易出现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

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

文/None_Ling(简书作者)
原文链接:http://www.jianshu.com/p/4585c1bd3fb0

更多相关文章

  1. Android实现录制视频
  2. android实现应用程序无图标(快捷方式)问题.
  3. android RadioButton 点击时候出现点击声音的效果
  4. Android(安卓)InputMethodManager 导致的内存泄露及解决方案
  5. android上传视频
  6. Android(安卓)ScrollViewy与HorizontalScrollView实现上下左右滚
  7. Android判断文件类型(视频、音频、图片等)
  8. Android(安卓)视频缩略图之MediaMetadataRetriever
  9. Android实现录制视频

随机推荐

  1. Android应用程序在手机上运行的步骤
  2. Android(安卓)wifi的WifiInfo对象详解
  3. Android仿QQ圆形头像
  4. android manifest.xml中元素含义
  5. android httpclient 上传文件
  6. Android(安卓)P Launcher APP替换图标不
  7. Android蓝牙耳机接听挂断电话流程
  8. android:windowSoftInputMode属性使用
  9. Android的NDK开发(1)————Android(安
  10. Android输入法扩展之外接键盘中文输入