最近在一家公司实习,要求我在Android上找到播放器实现后台播放的方法,通过研究网易云视频中的播放器,我找到了其中的方法,虽然我觉得网易的方法有点取巧。
1. 问题描述
网易云视频播放器在播放过程中切换到后台,即按HOME键和锁屏时视频依旧在播放,用户可以听到声音。
2. 后台原理
2.1. HOME键
程序运行->按HOME键
Activity调用的顺序是onPause->onStop
SurfaceView调用了surfaceDestroyed方法
然后再切回程序
Activity调用的顺序是onRestart->onStart->onResume
SurfaceView调用了surfaceCreated->surfaceChanged方法
2.2. 锁屏
而对于锁屏,其执行流程则是:
Activity只调用onPause方法
解锁后Activity调用onResume方法
SurfaceView中surfaceholder.callback的所有方法都没有执行
3. 实现方法
3.1. 网易云视频后台播放
网易云视频播放器在不使用Service的情况下可以在软件解码下实现后台播放,主要利用了在SurfaceView调用surfaceDestory方法时,不释放mediaplayer资源。
3.2. 主要代码
public void surfaceDestroyed(SurfaceHolder holder) {
mSurfaceHolder = null;
if (mMediaController != null) mMediaController.hide();
if (mMediaPlayer != null) {
if(mHardwareDecoder) {
mSeekWhenPrepared = mMediaPlayer.getCurrentPosition();
if (mMediaPlayer != null) {
mMediaPlayer.reset();
mMediaPlayer.release();
mMediaPlayer = null;
mCurrState = IDLE;
}
isBackground = true;
}
else if (!mPauseInBackground) {
mMediaPlayer.setDisplay(null);
isBackground = true;
}
else {
pause();
isBackground = true;
}
mNextState = RESUME;
}
}
};
当程序切换到后台时,会执行上面这段代码,由于选择的是软件解码mHardwareDecoder的值为false,所以直接跳到else if (!mPauseInBackground),也就使得mediaplayer资源不释放,从而实现了后台播放。
3.3. 在何时释放了mediaplayer资源
当Activity结束时会调用OnDestory,在此时释放资源。
@Override protected void onDestroy() { Log.d(TAG, "NEVideoPlayerActivity onDestroy"); mVideoView.release_resource(); super.onDestroy(); } public void release_resource() { if (mMediaPlayer != null) { mMediaPlayer.reset(); mMediaPlayer.release(); mMediaPlayer = null; mCurrState = IDLE; } }