MediaPlayer的prepareAsync不回调onPrepared问题

Posted diffx

tags:

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

一、问题排查

debug调试的framework日志信息:

技术图片

根据日志,进入MediaPlayer的framework层看源码

STEP 1

先从

V/MediaPlayerNative: constructor
V/MediaPlayerNative: setListener

https://android.googlesource.com/platform/frameworks/av/+/master/media/libmedia/mediaplayer.cpp

技术图片

可以看到这是正常的new了一个C++层的MediaPlayer

https://android.googlesource.com/platform/frameworks/base/+/56a2301/media/jni/android_media_MediaPlayer.cpp?autodive=0%2F%2F%2F%2F%2F

技术图片

以及设置了一个Java层的弱引用给C++层的MediaPlayer监听,目前一切正常

STEP 2

再看后面的日志:

V/MediaPlayerNative: reset
......
V/MediaPlayerNative: setVideoSurfaceTexture
V/MediaPlayerNative: prepareAsync

https://android.googlesource.com/platform/frameworks/base/+/56a2301/media/jni/android_media_MediaPlayer.cpp?autodive=0%2F%2F%2F%2F%2F

技术图片

可以看到这里对MediaPlayer的设置一切正常,没有异常。

包括后面通过url取获取HTTP流,以及获取大小都正常。

STEP 3

再看后面的日志:

V/PlayerBase: baseRelease() piid=679 state=1
......

https://android.googlesource.com/platform/frameworks/base/+/master/media/java/android/media/PlayerBase.java

技术图片

发现MediaPlayer的父类PlayerBase居然被release了???

https://android.googlesource.com/platform/frameworks/base/+/master/media/java/android/media/MediaPlayer.java

技术图片

STEP 4

可以看到,这是MediaPlayer被系统给GC了。

V/MediaPlayerNative: setListener
    disconnect

https://android.googlesource.com/platform/frameworks/base/+/56a2301/media/jni/android_media_MediaPlayer.cpp?autodive=0%2F%2F%2F%2F%2F

技术图片

技术图片

可以看到,这里是最后C++层的MediaPlayer也做了release

二、原因分析

通过debug调试日志,可以分析出问题出在MediaPlayer被JVM的GC调用了finalize

三、解决办法

方案一

在调用MediaPlayer的prepareAsync后,开启一个异步延时线程,判断是否prepare成功,如果失败,则将MediaPlayer重置,在设置dataSource后再来一次prepare。

方案二

接入AOP框架,拦截MediaPlayer的finalize方法,在被GC系统调用前,记录状态改变。再做后续的重试处理。

考虑到AOP框架的大小,一般都上10M,如果考虑包体大小,可以采纳方案一,否则推荐方案二。

以上是关于MediaPlayer的prepareAsync不回调onPrepared问题的主要内容,如果未能解决你的问题,请参考以下文章

MediaPlayer.prepareAsync 的 IllegalStateException

Android MediaPlayer播放prepareAsync called in state 8解决办法

E/MediaPlayer: start called in state 4, mPlayer(0xcc719a40)解决

MediaPlayer 和 AudioTrack 不输出相同的声音

mediaplayer不能播放视频怎么办

MediaPlayer 在第一次运行时不工作