Android 服务和MediaPlayer-控制屏幕旋转和应用程序退出
已解决-请参阅答案 我正在处理一个使用MediaPlayer类播放音乐的服务的应用程序 我在屏幕旋转和离开应用程序时遇到问题。我丢失了MediaPlayer对象或服务本身的引用或状态。我花了这么多时间在这上面,真的不知道出了什么问题 我在活动的Android 服务和MediaPlayer-控制屏幕旋转和应用程序退出,android,service,android-service,android-mediaplayer,status,Android,Service,Android Service,Android Mediaplayer,Status,已解决-请参阅答案 我正在处理一个使用MediaPlayer类播放音乐的服务的应用程序 我在屏幕旋转和离开应用程序时遇到问题。我丢失了MediaPlayer对象或服务本身的引用或状态。我花了这么多时间在这上面,真的不知道出了什么问题 我在活动的onResume中启动并绑定到服务: @Override protected void onResume() { Intent intent=new Intent(getApplicationContext(), M
onResume
中启动并绑定到服务:
@Override
protected void onResume()
{
Intent intent=new Intent(getApplicationContext(), MusicService.class);
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
super.onResume();
}
private ServiceConnection serviceConnection=new ServiceConnection()
{
public void onServiceConnected(ComponentName className, IBinder binder)
{
service=((MusicService.MyBinder)binder).getService();
}
public void onServiceDisconnected(ComponentName className)
{
service=null;
}
};
@Override
protected void onDestroy()
{
unbindService(serviceConnection);
super.onDestroy();
}
我通过ServiceConnection
获取对服务的引用:
@Override
protected void onResume()
{
Intent intent=new Intent(getApplicationContext(), MusicService.class);
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
super.onResume();
}
private ServiceConnection serviceConnection=new ServiceConnection()
{
public void onServiceConnected(ComponentName className, IBinder binder)
{
service=((MusicService.MyBinder)binder).getService();
}
public void onServiceDisconnected(ComponentName className)
{
service=null;
}
};
@Override
protected void onDestroy()
{
unbindService(serviceConnection);
super.onDestroy();
}
此时,我可以从我的服务调用任何方法:service.playMusic()代码>并且工作正常
我在onDestroy
中解除绑定:
@Override
protected void onResume()
{
Intent intent=new Intent(getApplicationContext(), MusicService.class);
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
super.onResume();
}
private ServiceConnection serviceConnection=new ServiceConnection()
{
public void onServiceConnected(ComponentName className, IBinder binder)
{
service=((MusicService.MyBinder)binder).getService();
}
public void onServiceDisconnected(ComponentName className)
{
service=null;
}
};
@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')中调用start
求你了,需要帮忙。提前谢谢
@Override
public IBinder onBind(Intent intent) {
player=MediaPlayer.create(getApplicationContext(), R.raw.tumbler);
player.setLooping(true);
player.setVolume(80, 80);
return binder;
}
每次绑定到服务时,您都在初始化MediaPlayer
,并且从未停止上一个实例。不要在onBind()
中启动媒体,等待服务发出启动/停止媒体播放器的命令。服务比活动寿命长(这就是它们的设计目的),因此,在活动被破坏后,它继续运行也就不足为奇了。除非你特别告诉它,否则这是预期的行为。如果您希望媒体播放器在活动打开时继续运行,您可能希望使用无头片段来保留一个保留片段,该片段可以在onCreate()
/onDestroy()
中为您管理MediaPlayer
我脑子里乱七八糟的(还有代码),但最后它还是起作用了。
如果这不是正确的方法,请让我知道
我的第一个问题是:当应用程序退出时,服务没有被破坏,MediaPlayer正在播放,直到我强制关闭应用程序。如果我没有强制关闭,在应用程序重新启动时,我有两个MediaPlayer同时播放,以此类推
原因:我没有手动终止服务。
解决方案:在活动的ondestory()
上,调用unbindService()
和stopService()
:
第二个问题是:当屏幕旋转时,我丢失了MediaPlayer的对象引用,音乐失去了控制,因为我无法访问对象。
原因:设计不好。我正在将MediaPlayer设置为服务的onBind()方法感谢@kcopock。他注意到了。因此,当屏幕旋转时,调用了Activity的onCreate(),其中包含bindService(),从而创建了新的MediaPlayer对象,甚至没有清理以前的实例。
解决方案:只需将该代码移到另一个未自动调用的部分,并在应用程序启动时手动调用一次,而不是每次通过configChanges重新创建活动时
所以,基本上我就是这样修复的,希望对其他用户有所帮助。
干杯。在他的情况下,他没有启动服务(他只是用BIND_AUTO_CREATE标志调用了bindService),因此当活动被销毁时,服务将被销毁。创建多个实例是正确的。我修正了这个问题,但是当我旋转屏幕时,MediaPlayer的引用变为null,我得到了相应的异常。此外,我尝试在服务被破坏时停止播放器(onDestroy),它在我退出应用程序时工作,也在我旋转屏幕时工作。我只想在退出时停止。我也修复了null引用,返回START\u STICKY并在绑定之前调用startService()。所以现在我只需要知道如何在轮换时继续比赛,而不是在退出时。请帮忙。