我有理解绑定到服务的问题 我创造了一个简单的歌曲播放器,提供播放歌曲的服务。 我创建了一个日志来跟踪绑定和解除绑定。 问题是当我退出应用程序时出现Unbinding日志但是当我回到应用程序时没有绑定日志消息,我能够控制播放和暂停该歌曲
public class PlayService extends Service {
MediaPlayer mPlayer;
public IBinder mBinder=new LocalBinder();
@Override
public void onCreate() {
super.onCreate();
Log.i("TAG","Create");
mPlayer=MediaPlayer.create(this,R.raw.askme);
}
//since we want the song to be played in the background then we need to start the service
@Override
public int onStartCommand(Intent intent,int flags, int startId) {
Log.i("TAG","Start");
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
stopSelf();
}
});
return Service.START_NOT_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.i("TAG","Bind");
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
Log.i("TAG","Unbind");
return super.onUnbind(intent);
}
@Override
public void onRebind(Intent intent) {
Log.i("TAG","ReBind");
super.onRebind(intent);
}
@Override
public void onDestroy() {
Log.i("TAG","Destroy");
mPlayer.release();
super.onDestroy();
}
//here are the play and pause methods frm the user
public void playSong(){
mPlayer.start();
}
public void pauseSong(){
mPlayer.pause();
}
public boolean isPlaying(){
return mPlayer.isPlaying();
}
//since Binder already Extends IBinder so
//we can create LocalBinder Class which extends IBinder Interface
public class LocalBinder extends Binder{
//this method for returning an instance of our service in the MainActivity
public PlayService getService(){
return PlayService.this;
}
}
}
和主要活动如下
public class MainActivity extends AppCompatActivity {
public static final String TAG ="TAG" ;
public PlayService mPlayService;
private Button mDownloadButton;
private Button mSongButton;
private boolean mBound=false;
private ServiceConnection mServiceConnection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
//the iBinder object is the returned value from onBind() method in our service
mBound=true;
//we need to get an instance of our service PlayerService so we can play or Pause the song
PlayService.LocalBinder binder = (PlayService.LocalBinder) iBinder;
//and here finally we are getting an instance of our service
mPlayService= binder.getService();
if (mPlayService.isPlaying()){
mSongButton.setText("Pause");
}
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
mBound=false;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDownloadButton=(Button) findViewById(R.id.download_button);
mSongButton=(Button) findViewById(R.id.song_button);
mDownloadButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this,"downloading",Toast.LENGTH_LONG).show();
for (String song:Playlist.songs){
Intent intent=new Intent(MainActivity.this,StartDownloadService.class);
intent.putExtra(TAG,song);
startService(intent);
}
}
});
mSongButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//here we can play or Pause the song
//but first we need to know if we are already bound to the service
if (mBound){
if (mPlayService.isPlaying()){
mPlayService.pauseSong();
mSongButton.setText("Play");
}else {
//but here we need the service to be started and keep playing in the background
//even if we unbound from the service when we exit the App
Intent intent=new Intent(MainActivity.this,PlayService.class);
startService(intent);
mPlayService.playSong();
mSongButton.setText("Pause");
}
}
}
});
}
@Override
protected void onResume() {
Intent intent=new Intent(this,PlayService.class);
bindService(intent,mServiceConnection, Context.BIND_AUTO_CREATE);
super.onResume();
}
@Override
protected void onStop() {
super.onStop();
if (mBound){
unbindService(mServiceConnection);
mBound=false;
}
}
}
如果有人可以解释
答案 0 :(得分:0)
您在代码中启动了两次服务。 一旦作为启动服务,然后作为绑定服务。删除已启动的服务代码,并且很可能它应该按预期工作。
从代码中删除
Intent intent=new Intent(MainActivity.this,PlayService.class);
startService(intent);
mPlayService.playSong();
mSongButton.setText("Pause");
因为你在Resume()方法的中绑定服务。
Intent intent=new Intent(this,PlayService.class);
bindService(intent,mServiceConnection, Context.BIND_AUTO_CREATE);
答案 1 :(得分:0)
你应该开始并绑定这样的音乐服务:
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart invoked !");
// Start/Bind to play back service
Intent serviceIntent = new Intent(this, PlayService.class);
if (isMyServiceRunning(PlayService.class)
&& mBound== false) {
this.bindService(serviceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
} else {
this.startService(serviceIntent);
this.bindService(serviceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
Log.i(TAG, "Media Player service is created new -------------------");
}
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop invoked !");
if(mBound) {
Log.i(TAG, "unbinding service !");
unbindService(mServiceConnection);
mBound= false;
}
}
检查服务是否正在运行:
/**
* Utility function to check if a service is running.
*/
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
希望这会对你有帮助!
答案 2 :(得分:0)
我找到了原因
系统调用您服务的onBind()方法,仅在第一个客户端绑定时检索IBinder。然后,系统将相同的IBinder传递给任何其他绑定的客户端,而无需再次调用onBind()。 这就是为什么我没有从onBind()和onUnbind()方法获取Log消息,但是我在onServiceConnected()中使用了一条日志消息,当我再次运行App时我得到了它。