Android MediaPlayer在服务屏幕旋转中播放视频流

Android MediaPlayer在服务屏幕旋转中播放视频流,android,android-service,android-mediaplayer,android-service-binding,Android,Android Service,Android Mediaplayer,Android Service Binding,我想用视频播放器创建活动,使用MediaPlayer类和SurfaceView显示在线流。我在单独的服务中创建MediaPlayer,这样在屏幕旋转后,播放器就不必再次创建,也不必连接到流。我的问题是,我不知道如何编写活动,所以我的服务不会在每次屏幕旋转后启动 下面的代码,在onStart()中,我启动了服务,但我不知道如何更改它,所以它并不是每次都启动 public class VideoPlayerActivity extends Activity implements SurfaceHol

我想用视频播放器创建活动,使用MediaPlayer类和SurfaceView显示在线流。我在单独的服务中创建MediaPlayer,这样在屏幕旋转后,播放器就不必再次创建,也不必连接到流。我的问题是,我不知道如何编写活动,所以我的服务不会在每次屏幕旋转后启动

下面的代码,在onStart()中,我启动了服务,但我不知道如何更改它,所以它并不是每次都启动

public class VideoPlayerActivity extends Activity implements SurfaceHolder.Callback {
    private String path;
    private SurfaceHolder vidHolder;
    private SurfaceView vidSurface;
    private VideoService videoService;
    private Intent playIntent;
    private boolean videoBound = false;

    private ServiceConnection musicConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            VideoService.VideoBinder binder = (VideoService.VideoBinder) service;
            videoService = binder.getService();
            videoService.setUrl(path);
            videoBound = true;
            if (vidHolder != null && videoService.getMediaPlayer() != null) {
                videoService.getMediaPlayer().setDisplay(vidHolder);
                videoService.playVideo();
            }
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            videoBound = false;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_player);
        path = "https://archive.org/download/ksnn_compilation_master_the_internet/ksnn_compilation_master_the_internet_512kb.mp4"; //TODO tmp
        playIntent = new Intent(this, VideoService.class);
        bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE);
        startService(playIntent);
        vidSurface = (SurfaceView) findViewById(R.id.surfView);
        vidHolder = vidSurface.getHolder();
        vidHolder.addCallback(VideoPlayerActivity.this);
    }

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        if (videoService != null && videoService.getMediaPlayer() != null) {
            videoService.getMediaPlayer().setDisplay(vidHolder);
        } 
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
        Log.d("ServiceConnection", "surfaceChanged  " + i + "   " + i1 + "   " + i2);
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        Log.d("ServiceConnection", "surfaceDestroyed");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(musicConnection);
        stopService(playIntent);
        videoService = null;
    }
}
服务类别:

public class VideoService extends Service implements OnPreparedListener {
    private MediaPlayer player;
    private String path;
    private final IBinder musicBind = new VideoBinder();

    @Override
    public void onCreate() {
        Log.d("VideoService", "onCreate");
        super.onCreate();
        player = new MediaPlayer();
        initMusicPlayer();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return musicBind;
    }

    @Override
    public boolean onUnbind(Intent intent){
        player.stop();
        player.release();
        return false;
    }

    public void initMusicPlayer() {
        player.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
        player.setAudioStreamType(AudioManager.STREAM_MUSIC);
        player.setOnPreparedListener(this);
    }

    public void playVideo() {
        try {
            player.setDataSource(path);
            player.prepareAsync();
        } catch (IOException e) {}
    }

    @Override
    public void onPrepared(MediaPlayer mediaPlayer) {
        mediaPlayer.start();
    }

    public void setUrl(String url) {
        path = url;
    }

    public MediaPlayer getMediaPlayer() {
        return player;
    }

    public class VideoBinder extends Binder {
        public VideoService getService() {
            return VideoService.this;
        }
    }
}

您可以检查
savedInstanceState
是否为null,以仅在新创建活动时启动服务

if (savedInstanceState == null) {
        startService...
}
或者通过添加

android:configChanges="orientation|keyboardHidden|screenSize"

到清单中的活动。像这样,onCreate将不再在轮换时调用。

您可以检查
savedInstanceState
是否为null,以仅在新创建活动时启动服务

if (savedInstanceState == null) {
        startService...
}
或者通过添加

android:configChanges="orientation|keyboardHidden|screenSize"

到清单中的活动。像这样,onCreate将不再轮流调用。

多次启动服务有什么问题?@pskink每次创建MediaPlayer时,它必须连接到流(需要几秒钟)。如果您在
onCreate
中创建MediaPlayer,该方法只调用一次,并非每次调用
startService
,更重要的是,如果您在
ondestory
中调用
unbindService
,则应在
onCreate
中调用
bindService
,而不是在
onStart
中调用
stopService(playIntent)
多次启动服务有什么问题?@pskink每次创建MediaPlayer时,它必须连接到流(需要几秒钟)您在
onCreate
中创建MediaPlayer时,该方法只调用一次,而不是每次调用
startService
,还有,如果您在
onDestroy
中调用
unbindService
,则应在
onCreate
中调用
bindService
,而不是在
onStart
中调用
stopService(playIntent)