Service和MediaPlayer - 控制屏幕旋转和App退出

时间:2014-10-06 20:01:19

标签: android service android-service android-mediaplayer status

已解决 - 请参阅答案。

我正在处理一个使用服务与MediaPlayer类播放音乐的应用程序。

我遇到屏幕旋转问题,当我离开应用程序时。我丢失了MediaPlayer对象或服务本身的引用或状态。用这么多时间工作,真的不知道出了什么问题。

我开始并绑定到Activity的onResume

中的服务
    @Override
    protected void onResume()
    {
        Intent intent=new Intent(getApplicationContext(), MusicService.class);
        bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

        super.onResume();
    }

我使用ServiceConnection

获取对服务的引用
    private ServiceConnection serviceConnection=new ServiceConnection()
    {
        public void onServiceConnected(ComponentName className, IBinder binder)
        {
            service=((MusicService.MyBinder)binder).getService();
        }

        public void onServiceDisconnected(ComponentName className)
        {
            service=null;
        }
    };

此时我可以通过我的服务调用任何方法:service.playMusic();并且工作正常。

我在onDestroy取消绑定:

@Override
protected void onDestroy()
{
    unbindService(serviceConnection);
    super.onDestroy();
}

这是我的服务类:

public class MusicService extends Service
{
    private final IBinder binder=new MyBinder();
    private MediaPlayer player;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        return Service.START_REDELIVER_INTENT;
    }

    @Override
    public IBinder onBind(Intent intent)
    {
        player=MediaPlayer.create(getApplicationContext(), R.raw.tumbler);
        player.setLooping(true);
        player.setVolume(80, 80);

        return binder;
    }

    public class MyBinder extends Binder
    {
        public MusicService getService()
        {
            return MusicService.this;
        }
    }

    public void play()
    {
        player.start();
        Log.d("MUSIC SERVICE", "play!");
    }
}

所以,问题是:

  • 退出时,服务和音乐会继续播放。我想阻止它。如果我再次进入应用程序,则会再次启动相同的服务并且音乐正在播放两次。我想阻止它。

  • 当我旋转屏幕时,MediaPlayer继续播放(我想要),但我不能再调用pause(),start()等因为状态已经改变(我收到消息'MediaPlayer :暂停在状态8'和'MediaPlayer中调用:在状态0中调用')。

请,需要一些帮助。提前谢谢!

2 个答案:

答案 0 :(得分:2)

@Override
public IBinder onBind(Intent intent) {
    player=MediaPlayer.create(getApplicationContext(), R.raw.tumbler);
    player.setLooping(true);
    player.setVolume(80, 80);

    return binder;
}

每次绑定到服务时都会重新初始化MediaPlayer并且永远不会停止前一个实例。不要在onBind()中启动媒体,等待服务命令启动/停止媒体播放器。服务比活动更长(这就是它们的设计目的),因此它在活动被销毁后继续播放也就不足为奇了。除非你特别告诉它,否则这是预期的行为。如果您想要一个在活动开放时继续前进的媒体播放器,您可能希望使用无头片段来保留一个可以在MediaPlayer中为您管理onCreate()的保留片段/ onDestroy()

答案 1 :(得分:0)

嗯,我想我明白了。

我脑子里乱糟糟的(和代码),但最后它还在工作 如果这不是正确的方法,请告诉我。

我的第一个问题是:当应用程序退出服务时,销毁并且MediaPlayer正在播放,直到我强行关闭应用程序。如果我没有强行关闭,在App重新启动时,我有2个MediaPlayers同时播放,等等。

原因:我没有手动终止我的服务 解决方案:在活动onDestroy()上,致电unbindService()stopService()

@Override
protected void onDestroy()
{
    super.onDestroy();

    unbindService(serviceConnection);
    stopService(new Intent(getApplicationContext(), MusicService.class));
}

第二个问题是:当屏幕旋转时,我丢失了MediaPlayer的对象引用,音乐失控,因为我无法访问该对象。 /> 原因:设计不当。我正在将MediaPlayer设置为Service&#39的onBind()方法。 感谢@kcoppock 。他注意到了。因此,当屏幕旋转时,Activity的onCreate()被调用,我有bindService(),导致创建新的MediaPlayer对象,甚至没有清理前一个实例。
解决方案:只需将该代码移出到另一个未自动调用的部分,并在应用启动时手动调用一次,而不是每次都通过configChanges重新创建Activity。

所以,基本上就是我修复它的方式,希望它对其他用户有所帮助 欢呼声。