前言
好久没有发布文章了,整个5月底6月初的状态都在准备复习与面试的路上,最终选择了一家薪资待遇都不错的公司。之后会回忆一下面试相关的内容做一下复盘。
问题发现
目前公司的登录引导界面背景是无声视频,当然采用VideoView来加载视频。初到公司,熟悉业务,偶然间发现第三方音乐播放器播放音乐在后台,然后打开公司的App,启动引导页,发现音乐被暂停了。其实想想很简单,就是VideoView的焦点被获取了,直接取消获取音频焦点就万事大吉了。
解决问题
因为之前使用VideoView,一般都是有音乐的,没有注意到这个问题。找了找发现并没有能够取消获取音频焦点的Api,然后就看了看源码。
Android O 8.0 之前
private void openVideo() {
if (mUri == null || mSurfaceHolder == null) {
// not ready for playback just yet, will try again later
return;
}
// we shouldn't clear the target state, because somebody might have
// called start() previously
release(false);
// 1
AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
am.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
//... 省略部分代码
}
1处代码可见,在我们setVideoURI的时候,会去调用openVideo()的方法,该方法在8.0之前会请求音频焦点,并且默认就是申请, 所以会导致其他正在播放的音频停止。
Android 8.0 之后
/**
* Sets which type of audio focus will be requested during the playback, or configures playback
* to not request audio focus. Valid values for focus requests are
* {@link AudioManager#AUDIOFOCUS_GAIN}, {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT},
* {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}, and
* {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}. Or use
* {@link AudioManager#AUDIOFOCUS_NONE} to express that audio focus should not be
* requested when playback starts. You can for instance use this when playing a silent animation
* through this class, and you don't want to affect other audio applications playing in the
* background.
* @param focusGain the type of audio focus gain that will be requested, or
* {@link AudioManager#AUDIOFOCUS_NONE} to disable the use audio focus during playback.
*/
public void setAudioFocusRequest(int focusGain) {
if (focusGain != AudioManager.AUDIOFOCUS_NONE
&& focusGain != AudioManager.AUDIOFOCUS_GAIN
&& focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT
&& focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
&& focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE) {
throw new IllegalArgumentException("Illegal audio focus type " + focusGain);
}
mAudioFocusType = focusGain;
}
/**
* Sets the {@link AudioAttributes} to be used during the playback of the video.
* @param attributes non-null AudioAttributes
.
*/
public void setAudioAttributes(@NonNull AudioAttributes attributes) {
if (attributes == null) {
throw new IllegalArgumentException("Illegal null AudioAttributes");
}
mAudioAttributes = attributes;
}
private void openVideo() {
if (mUri == null || mSurfaceHolder == null) {
// not ready for playback just yet, will try again later
return;
}
// we shouldn't clear the target state, because somebody might have
// called start() previously
release(false);
if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) {
// TODO this should have a focus listener
mAudioManager.requestAudioFocus(null, mAudioAttributes, mAudioFocusType, 0 /*flags*/);
}
}
在8.0之后提供了setAudioFocusRequest()的方法,也支持在xml布局中设置。但是8.0之前怎么办呢?
解决方案就是因为业务需要,所以就可以复制一份VideoView源码,并且注释requestAudioFocus()的方法。
总结
问题很简单,不过其实文章目的是介绍一种方式方法,可以看Google工程师处理问题的解决方案,以及一些在ASOP中是怎样fix bug的。
- 首先 https://cs.android.com/ 这个是我用来看ASOP的网站。
2.选择对应的版本,查看git提交记录。
因此这个就是找到本期问题的方式方法,特此记录下。