JiaoZiVideoPlayer
JiaoZiVideoPlayer copied to clipboard
使用exoplayer内核引起的在子线程操作了UI
**什么jzvd版本 6.4.1 **是否和安卓版本有关系,什么版本 否 **是否和特定品牌的手机机型有关系,什么机型 否 **相关log是什么 W/SimpleExoPlayer: Player is accessed on the wrong thread. See https://google.github.io/ExoPlayer/faqs.html#what-do-player-is-accessed-on-the-wrong-thread-warnings-mean **复现流程 播放视频都会出现 **最好有截图或者视频说明情况
使用exoplayer内核进行视频播放会产品此警告,而且确实在app退到后台时偶尔会发生在子线程操作view导致的crash。
有crash的log吗,这个log应该是播放就有,不导致崩溃的log
1 android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6877)
2 android.view.ViewRootImpl.playSoundEffect(ViewRootImpl.java:5759) 3 android.view.View.playSoundEffect(View.java:19295) 4 android.view.View.performClick(View.java:5230) 5 cn.jzvd.Jzvd$1.onAudioFocusChange(Jzvd.java:84) 6 android.media.AudioManager$FocusEventHandlerDelegate$1.handleMessage(AudioManager.java:2318) 7 android.os.Handler.dispatchMessage(Handler.java:102) 8 android.os.Looper.loop(Looper.java:179) 9 android.os.HandlerThread.run(HandlerThread.java:61)
好像是Jzvd这个类里面的onAudioFocusChangeListener的监听回调中的操作都可能会导致这个子线程操作view的crash。
因为MediaPlayer的release()函数是需要在线程中调用的,因为会增加界面的流畅性,频繁切换不同JZVD播放不会卡顿,所以根据框架exo也会在线程中启动和release()
这个过程常规下没有问题,兄弟研究一下onAudioFocusChangeListener调用了哪个exo的函数导致崩溃,现在需要非常明确的复现出来。
调研目的非常明确:加一个按钮,把复现过程放到按钮里,播放的时候点击按钮就会崩溃。
感觉把问题研究到这种程度,才算研究明白不糊涂。
debug了下发现其实不是视频引起的= = 而是当视频播放时其他应用占用了音频触发了onAudioFocusChangeListener中的onAudioFocusChange监听,而这个监听是在子线程中的,那么此时去执行释放就涉及到了view的改变,所以crash了。 使用JZMediaManager.instance().mainThreadHandler.post来操作可以解决这个问题。 还有就是在监听到AUDIOFOCUS_LOSS时不应该是暂停视频吗?为什么是释放呢?
有具体的详细解决办法吗?哪行代码出得错,怎么修改。
这阵子需求爆多抱歉回复晚了 我现在的处理方式是在进入onAudioFocusChange方法时对相关操作放在JZMediaManager.instance().mainThreadHandler.post里,测试后确定不会再crash,具体代码如下 case AudioManager.AUDIOFOCUS_LOSS: if (player != null && player.currentState == Jzvd.CURRENT_STATE_PLAYING) { JZMediaManager.instance().mainThreadHandler.post(() -> { try { Jzvd player1 = JzvdMgr.getCurrentJzvd(); if (player1 != null) { player1.startButton.performClick(); } } catch (Exception e) { JZMediaManager.instance().positionInList = -1; JZMediaManager.instance().releaseMediaPlayer(); e.printStackTrace(); } }); } Log.d(TAG, "AUDIOFOCUS_LOSS [" + this.hashCode() + "]"); break; case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: if (player != null && player.currentState == Jzvd.CURRENT_STATE_PLAYING) { JZMediaManager.instance().mainThreadHandler.post(() -> { try { Jzvd player1 = JzvdMgr.getCurrentJzvd(); if (player1 != null) { player1.startButton.performClick(); } } catch (Exception e) { JZMediaManager.instance().positionInList = -1; JZMediaManager.instance().releaseMediaPlayer(); e.printStackTrace(); } }); } Log.d(TAG, "AUDIOFOCUS_LOSS_TRANSIENT [" + this.hashCode() + "]"); break;
ps:加try catch是因为急着上线怕有闪失求个安稳= =
重写了Jzvd.onAudioFocusChangeListener
使用主线程,减少了大量crash
能分享一下吗------------------ 原始邮件 ------------------ 发件人: "CodeBaker"[email protected] 发送时间: 2019年6月4日(星期二) 上午9:56 收件人: "lipangit/JiaoZiVideoPlayer"[email protected]; 抄送: "Nathen"[email protected];"Comment"[email protected]; 主题: Re: [lipangit/JiaoZiVideoPlayer] 使用exoplayer内核引起的在子线程操作了UI (#2404)
重写了Jzvd.onAudioFocusChangeListener使用主线程,减少了大量crash
— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.
@lipangit
报错信息,线上版本有超过0.5%的用户因为这个报错crash
因为解决方法楼上的大哥@csbz17027 已经贴出来了所以刚才没有贴出来,具体代码
Jzvd.onAudioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() {
@Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
break;
case AudioManager.AUDIOFOCUS_LOSS:
JZMediaManager.instance().mainThreadHandler.post(() -> {
try {
Jzvd.releaseAllVideos();
} catch (IllegalStateException e) {
e.printStackTrace();
}
});
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
JZMediaManager.instance().mainThreadHandler.post(() -> {
try {
Jzvd player = JzvdMgr.getCurrentJzvd();
if (player != null && player.currentState == Jzvd.CURRENT_STATE_PLAYING) {
player.startButton.performClick();
}
} catch (IllegalStateException e) {
e.printStackTrace();
}
});
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
break;
}
}
};
我也碰到这个问题了,请问修复了吗
有时间我把它们放到develop上
JZMediaManager.instance().mainThreadHandler.post(() 新版本没有JZMediaManager了,需要怎么搞,使用JZMediaInterface中的handler吗?
用哪个版本的jzvd去对应版本找jzmediaexo 不同版可能有点区别
---原始邮件--- 发件人: @.> 发送时间: 2021年4月29日(周四) 上午10:03 收件人: @.>; 抄送: @.@.>; 主题: Re: [lipangit/JiaoZiVideoPlayer] 使用exoplayer内核引起的在子线程操作了UI (#2404)
JZMediaManager.instance().mainThreadHandler.post(() 新版本没有JZMediaManager了,需要怎么搞,使用JZMediaInterface中的handler吗?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.