Firebase Crashlytics捕获MediaPlayer相关ANR问题求助
排查Firebase Crashlytics捕获的MediaPlayer相关ANR问题
已通过Firebase Crashlytics捕获到以下ANR错误,该问题已困扰数月,现借助Crashlytics进一步排查成因,恳请协助:
ANR堆栈信息
main (native): tid=1 systid=7666 #00 pc 0x9a4a4 libc.so (__ioctl + 8) #01 pc 0x6754f libc.so (ioctl + 30) #02 pc 0x2f1b5 libbinder.so (android::IPCThreadState::talkWithDriver(bool) + 228) #03 pc 0x2ff39 libbinder.so (android::IPCThreadState::waitForResponse(android::Parcel*, int*) + 36) #04 pc 0x2fce3 libbinder.so (android::IPCThreadState::transact(int, unsigned int, android::Parcel const&, android::Parcel*, unsigned int) + 134) #05 pc 0x2a577 libbinder.so (android::BpBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int) + 118) #06 pc 0x4291f libmedia.so (android::BpMediaPlayerService::create(android::sp<android::IMediaPlayerClient> const&, audio_session_t, android::content::AttributionSourceState const&) + 430) #07 pc 0x38b69 libmedia.so (android::MediaPlayer::setDataSource(int, long long, long long) + 220) #08 pc 0x50e3f libmedia_jni.so (android_media_MediaPlayer_setDataSourceFD(_JNIEnv*, _jobject*, _jobject*, long long, long long) + 146) at android.media.MediaPlayer._setDataSource(MediaPlayer.java) at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1354) at android.media.MediaPlayer.create(MediaPlayer.java:1047) at android.media.MediaPlayer.create(MediaPlayer.java:1015) at com.dev.myapp.activityone.playMediaPlayer(activityone.java:65) at com.dev.myapp.activityone$15.onFinish(activityone.java:10) at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:142) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:226) at android.os.Looper.loop(Looper.java:313) at android.app.ActivityThread.main(ActivityThread.java:8751) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
关联代码
public void playMediaPlayer(int id) { try { if (mediaPlayer != null || mediaPlayer.isPlaying()) { mediaPlayer.release(); mediaPlayer = new MediaPlayer(); } if (id == 1) { mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.sound1); } else if (id == 2) { mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.sound2); } if (PreferenceData.getSound(getApplicationContext())) { mediaPlayer.start(); } } catch (OutOfMemoryError e) { e.printStackTrace(); } }
问题分析
- 主线程阻塞触发ANR:从堆栈可见,ANR发生在
MediaPlayer.create执行阶段,该方法涉及与MediaPlayerService的跨进程(IPC)通信,在主线程执行时会阻塞UI线程,当IPC响应超时就会触发ANR。 - 资源管理逻辑漏洞:
- 条件判断
if (mediaPlayer != null || mediaPlayer.isPlaying())存在错误:若mediaPlayer为null,调用mediaPlayer.isPlaying()会直接抛出空指针异常;且后续new MediaPlayer()创建的实例会被MediaPlayer.create覆盖,造成不必要的资源泄漏。 - 释放资源后未将
mediaPlayer置为null,可能导致重复释放或空指针问题。
- 条件判断
- 异常捕获不完整:仅捕获
OutOfMemoryError,未处理MediaPlayer操作中常见的IllegalStateException等异常,可能导致线程异常阻塞。
修复方案
将MediaPlayer操作移至子线程:
避免在主线程执行MediaPlayer.create等耗时IPC操作,使用子线程处理初始化和播放逻辑,示例如下:public void playMediaPlayer(int id) { new Thread(() -> { try { if (mediaPlayer != null) { if (mediaPlayer.isPlaying()) { mediaPlayer.stop(); } mediaPlayer.release(); mediaPlayer = null; } if (id == 1) { mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.sound1); } else if (id == 2) { mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.sound2); } if (mediaPlayer != null && PreferenceData.getSound(getApplicationContext())) { mediaPlayer.start(); // 播放完成后自动释放资源 mediaPlayer.setOnCompletionListener(mp -> { mp.release(); mediaPlayer = null; }); } } catch (Exception e) { e.printStackTrace(); // 异常后重置MediaPlayer if (mediaPlayer != null) { mediaPlayer.release(); mediaPlayer = null; } } }).start(); }修正资源管理逻辑:
- 移除多余的
mediaPlayer = new MediaPlayer(),因为MediaPlayer.create会自动创建并初始化MediaPlayer实例。 - 调整条件判断为
if (mediaPlayer != null),先检查非空再处理播放状态和释放操作,释放后将mediaPlayer置为null。
- 移除多余的
完善异常捕获:
将捕获范围扩大至Exception,覆盖MediaPlayer操作中的所有常见异常,避免未处理的异常导致线程阻塞或资源泄漏。优化MediaPlayer复用(可选):
若频繁播放少量固定音频,可提前初始化MediaPlayer实例并复用,减少重复创建和IPC调用次数,降低ANR风险。
内容的提问来源于stack exchange,提问作者Lechius
相关产品推荐
相关产品推荐

