使用service 和 surfaceView+mediaPalyer 播放视频点home键回到桌面,在打开视频后 surfaceView黑屏的问题,今天学习了老师service视频后,看老师做了一个 mediaPlayer的音频后台播放 ,于是按照老师的写法,自己又加了个视频播放 ,但是切到后台在切回来后 发现surfaceView不显示画面了, 百度了后发现 ,在切到后台后 surfaceView会走onDestroy方法 ,请问有什么办法解决呢?下边贴上代码 ,请大家帮忙看看。
ui层的展示
MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "MainActivity";
private Button button_play, button_resume;
private AppCompatSeekBar seekBar;
private SurfaceView surfaceView;
private IPlayerControl IPlayControl;
private PlayerConnection playerConnection;
int mWidth, mHeight;
int measuredHeight;
private SurfaceHolder holder;
private RelativeLayout relativeLayout;
private boolean isUserTouchProgessBar = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
initEvent();
initStartService();
initBindService();
}
private void initStartService() {
Intent intent = new Intent(this, PlayService.class);
startService(intent);
}
private void initBindService() {
Intent intent = new Intent(this, PlayService.class);
if (playerConnection == null) {
playerConnection = new PlayerConnection();
}
bindService(intent, playerConnection, BIND_AUTO_CREATE);
}
private class PlayerConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IPlayControl = (IPlayerControl) service;
IPlayControl.registerViewController(iPlayerViewControl);
}
@Override
public void onServiceDisconnected(ComponentName name) {
IPlayControl.unRegisterController();
IPlayControl = null;
}
}
private IPlayerViewControl iPlayerViewControl = new IPlayerViewControl() {
@Override
public void onStateChange(int state) {
switch (state) {
case PLAY_STATE_PLAYER:
//修改ui
button_play.setText("暂停");
break;
case PLAY_STATE_PAUSE:
case PLAY_STATE_STOP:
button_play.setText("播放");
break;
}
}
@Override
public void onSeekChange(final int seek) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (!isUserTouchProgessBar) {
seekBar.setProgress(seek);
}
}
});
}
@Override
public void onChangeParams(int w, int h) {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(w, h);
params.addRule(RelativeLayout.CENTER_IN_PARENT, relativeLayout.getId());
surfaceView.setLayoutParams(params);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceChanged() {
}
@Override
public void surfaceDestroyed() {
}
};
public void init() {
button_play = findViewById(R.id.button_play);
button_resume = findViewById(R.id.button_resume);
relativeLayout = findViewById(R.id.relativeLayout);
seekBar = findViewById(R.id.seek);
surfaceView = findViewById(R.id.surfaceView);
relativeLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mWidth = relativeLayout.getWidth();
measuredHeight = relativeLayout.getMeasuredHeight();
mHeight = relativeLayout.getHeight();
Log.d(TAG, "onGlobalLayout ===> mWidth =" + mWidth + "mHeight =" + mHeight);
holder.setFixedSize(mWidth, mHeight);
}
});
}
public void initEvent() {
button_play.setOnClickListener(this);
button_resume.setOnClickListener(this);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
isUserTouchProgessBar = true;
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
Log.d(TAG, "onStopTrackingTouch----->" + seekBar);
//停止拖动
if (IPlayControl != null) {
IPlayControl.seekTo(seekBar.getProgress());
}
isUserTouchProgessBar = false;
}
});
surfaceView.setZOrderOnTop(true);
holder = surfaceView.getHolder();
holder.setKeepScreenOn(true);
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.d(TAG, "surfaceCreated---->holder ===" + holder);
iPlayerViewControl.surfaceCreated(holder);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.d(TAG, "surfaceChanged---->holder ===" + holder);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d(TAG, "surfaceDestroyed---->holder ===" + holder);
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_play:
if (IPlayControl != null) {
IPlayControl.setSurfaceHolder(surfaceView.getHolder(), mWidth, mHeight);
IPlayControl.startAndPausePlay();
Log.d(TAG, "setSurfaceHolder---->holder ===" + surfaceView.getHolder());
}
break;
case R.id.button_resume:
if (IPlayControl != null) {
IPlayControl.stopPlay();
}
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (playerConnection != null) {
IPlayControl.unRegisterController();
unbindService(playerConnection);
}
}
}
PlayerPresenter 控制层
public class PlayerPresenter extends Binder implements IPlayerControl, MediaPlayer.OnPreparedListener, MediaPlayer.OnVideoSizeChangedListener {
private IPlayerViewControl iPlayerViewControl;
private int CurrentState = PLAY_STATE_STOP;
private MediaPlayer mediaPlayer;
private static final String TAG = "PlayerPresenter";
private SurfaceHolder surfaceView;
private int mWidth, mHeight;
private Timer timer;
private SeekTimeTask timeTask;
@Override
public void registerViewController(IPlayerViewControl iPlayerViewControl) {
this.iPlayerViewControl = iPlayerViewControl;
}
@Override
public void unRegisterController() {
this.iPlayerViewControl = null;
}
@Override
public void setSurfaceHolder(SurfaceHolder holder, int width, int height) {
this.surfaceView = holder;
this.mWidth = width;
this.mHeight = height;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void startAndPausePlay() {
if (CurrentState == PLAY_STATE_STOP) {
initMediaPlayer();
try {
File tempFile = new File("/sdcard/Movies/dsy.mp4");
FileInputStream fis = new FileInputStream(tempFile);
mediaPlayer.reset();
mediaPlayer.setDataSource(fis.getFD());
mediaPlayer.setDisplay(surfaceView);//把视频画面输出到SurfaceView中
Log.d(TAG, "surfaceView ===>" + surfaceView);
mediaPlayer.prepare();
mediaPlayer.start();
startTimer();
CurrentState = PLAY_STATE_PLAYER;
} catch (Exception e) {
e.printStackTrace();
}
} else if (CurrentState == PLAY_STATE_PLAYER) {
if (mediaPlayer != null) {
mediaPlayer.pause();
mediaPlayer.setDisplay(surfaceView);//把视频画面输出到SurfaceView中
stopTimer();
CurrentState = PLAY_STATE_PAUSE;
}
} else if (CurrentState == PLAY_STATE_PAUSE) {
if (mediaPlayer != null) {
mediaPlayer.setDisplay(surfaceView);//把视频画面输出到SurfaceView中
mediaPlayer.start();
startTimer();
CurrentState = PLAY_STATE_PLAYER;
}
}
if (iPlayerViewControl != null) {
iPlayerViewControl.onStateChange(CurrentState);
}
}
@Override
public void stopPlay() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();
stopTimer();
CurrentState = PLAY_STATE_STOP;
if (iPlayerViewControl != null) {
iPlayerViewControl.onStateChange(CurrentState);
}
mediaPlayer = null;
}
}
@Override
public void resumePlay() {
}
@Override
public void seekTo(int seek) {
Log.d(TAG, "seekTo ------->" + seek);
if (mediaPlayer != null) {
//做转换
int tarSeek = (int) (seek * 1.0f / 100 * mediaPlayer.getDuration());
Log.d(TAG, "tarSeek ------->" + tarSeek);
mediaPlayer.seekTo(tarSeek);
}
}
private void initMediaPlayer() {
if (mediaPlayer == null) {
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnVideoSizeChangedListener(this);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);//设置多媒体类型
}
}
@Override
public void onPrepared(MediaPlayer mp) {
int vWidth = mp.getVideoWidth();
int vHeight = mp.getVideoHeight();
Log.d(TAG, "onPrepared--> vWidth = " + vWidth + ", vHeight= " + vHeight);
int lw = mWidth;
int lh = mHeight;
if (vWidth > lw || vHeight > lh) {
// 如果video的宽或者高超出了当前屏幕的大小,则要进行缩放
float wRatio = (float) vWidth / (float) lw;
float hRatio = (float) vHeight / (float) lh;
// 选择大的一个进行缩放
float ratio = Math.max(wRatio, hRatio);
vWidth = (int) Math.ceil((float) vWidth / ratio);
vHeight = (int) Math.ceil((float) vHeight / ratio);
// 设置surfaceView的布局参数
if (iPlayerViewControl != null) {
iPlayerViewControl.onChangeParams(vWidth, vHeight);
}
} else {
if (iPlayerViewControl != null) {
iPlayerViewControl.onChangeParams(vWidth, vHeight);
}
}
}
@Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
Log.d(TAG, "onVideoSizeChanged--> width = " + width + ", height= " + height);
}
private void stopTimer() {
if (timeTask != null) {
timeTask.cancel();
timeTask = null;
}
if (timer != null) {
timer.cancel();
timer = null;
}
}
private void startTimer() {
if (timer == null) {
timer = new Timer();
}
if (timeTask == null) {
timeTask = new SeekTimeTask();
}
timer.schedule(timeTask, 0, 500);
}
private class SeekTimeTask extends TimerTask {
@Override
public void run() {
if (mediaPlayer != null && iPlayerViewControl != null) {
//获取当前的播放进度
int currentPosition = mediaPlayer.getCurrentPosition();
Log.d(TAG, "currentPosition ====>" + currentPosition);
Log.d(TAG, "getDuration ====>" + mediaPlayer.getDuration());
int curPosition = (int) (currentPosition * 1.0f / mediaPlayer.getDuration() * 100);
Log.d(TAG, "curPosition ====>" + curPosition);
iPlayerViewControl.onSeekChange(curPosition);
}
}
}
}
接口
IPlayerControl
public interface IPlayerControl {
int PLAY_STATE_PLAYER = 1;
int PLAY_STATE_PAUSE = 2;
int PLAY_STATE_STOP = 3;
int PLAY_STATE_EOOER = 5;
/**
* 把ui的接口设置给逻辑层
*/
void registerViewController(IPlayerViewControl iPlayerViewControl);
/**
* 取消接口的通知的注册
*/
void unRegisterController();
void setSurfaceHolder(SurfaceHolder holder, int width, int height);
void surfaceCreated(SurfaceHolder holder);
//开始播放
void startAndPausePlay();
//终止播放
void stopPlay();
//循环播放
void resumePlay();
//进度条
void seekTo(int seek);
}
接口
public interface IPlayerViewControl {
//播放状态的改变
void onStateChange(int state);
//进度条的改变
void onSeekChange(int seek);
void onChangeParams(int w,int h);
void surfaceCreated(SurfaceHolder holder);
void surfaceChanged();
void surfaceDestroyed();
}
服务 PlayService
public class PlayService extends Service {
private PlayerPresenter playerPresenter;
@Override
public void onCreate() {
super.onCreate();
if (playerPresenter == null) {
playerPresenter = new PlayerPresenter();
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return playerPresenter;
}
@Override
public void onDestroy() {
super.onDestroy();
playerPresenter = null;
}
}
xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<RelativeLayout
android:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="@color/colorBlack">
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp">
<Button
android:id="@+id/button_play"
android:layout_width="60dp"
android:layout_height="match_parent"
android:text="播放"
android:textSize="14sp" />
<Button
android:id="@+id/button_resume"
android:layout_width="60dp"
android:layout_height="match_parent"
android:layout_toRightOf="@+id/button_play"
android:text="重播"
android:textSize="14sp" />
<android.support.v7.widget.AppCompatSeekBar
android:id="@+id/seek"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/button_resume"
android:max="100" />
</RelativeLayout>
</LinearLayout>
您的每一个用心回答,都会让这个世界变得更美好一些!