2017-04-25 90 views
0

我有问题了解绑定到服务 我创建了一个简单的歌曲播放器,并提供播放歌曲的服务。 我创建了一个日志来跟踪绑定和解除绑定。 的问题是,当我退出该应用程序会出现解除绑定日志,但是当我回去的应用程序是没有约束力的日志消息,我能控制歌曲的播放和暂停,虽然Android服务绑定

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

您在代码中开始两次服务。 一次作为启动的服务,然后作为绑定服务。删除已启动的服务代码,很可能它应该按预期工作。

删除这从您的代码

Intent intent=new Intent(MainActivity.this,PlayService.class); 
       startService(intent); 
       mPlayService.playSong(); 
       mSongButton.setText("Pause"); 

因为你是在在简历绑定服务()方法。

Intent intent=new Intent(this,PlayService.class); 
bindService(intent,mServiceConnection, Context.BIND_AUTO_CREATE); 
+0

如果我不启动服务,歌曲将停止,如果我退出应用程序 –

+0

而不是您在其他部分中的startService意图,则还会在其他部分调用绑定服务代码。 –

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; 
    } 

希望这将帮助你!

0

我找到了原因

系统调用服务的onBind()方法来检索的IBinder只有当第一个客户端绑定。系统然后将相同的IBinder传递给绑定的任何其他客户端,而无需再次调用onBind()。 这就是为什么我没有从onBind()和onUnbind()方法获取日志消息,但我在onServiceConnected()中使用了日志消息,并且当我再次运行该应用程序时我得到了它。