如何取消绑定MusicService

时间:2015-10-21 11:47:56

标签: android service bind

我是Android的新手,我正在开发一款游戏应用程序,我想在后台播放音乐,音乐必须在所有活动中播放。另外,我正在从用户的设备中获取歌曲并将它们呈现在ListView中。用户在ListMusic活动中选择一首歌,然后他继续其他活动和我的目的是音乐将在后台继续。

我希望你理解这个过程,我也加入了JAVA。

现在,我遇到了这个错误:

活动com.example.summerproject.FirstActivity已泄露最初绑定的ServiceConnection com.example.summerproject.ListMusic$1@42116d20

从我的理解,问题是我不是UnBind每个活动的onDestroy()上的连接。有人知道如何解决它吗?我希望音乐能够在所有活动中继续进行,因此每次取消绑定服务可能会出现问题。

MusicService:

   public class MusicService extends Service implements
   MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener,
   MediaPlayer.OnCompletionListener
{
     private MediaPlayer player; //media player
     private ArrayList<Song> valuesList; //songs List
     private int songPosn;  //current position
     private final IBinder musicBind = new MusicBinder();

    public void onCreate()
     {

        super.onCreate(); 
        songPosn=0;
        player= new MediaPlayer();
        initMusicPlayer();

        player.setOnPreparedListener(this);
        player.setOnCompletionListener(this);
        player.setOnErrorListener(this);
     }

    @Override
    public IBinder onBind(Intent intent) 
    {
        //בעת התחברות 
        return musicBind;

    }

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

    public void initMusicPlayer() 
    {
          //set player properties
        player.setWakeMode(getApplicationContext(),
                PowerManager.PARTIAL_WAKE_LOCK);
                player.setAudioStreamType(AudioManager.STREAM_MUSIC);
    }

    public void playSong()
    {
         if(player != null) //אם נוצר כבר
            player.reset();

        Song songToPlay = valuesList.get(songPosn);
        long songId = songToPlay.getId();

        Uri trackUri = ContentUris.withAppendedId(
          android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
          songId);

        try{
              player.setDataSource(getApplicationContext(), trackUri);
            }
            catch(Exception e)
            {
              Log.e("MUSIC SERVICE", "Error setting data source", e);
            }
        player.setLooping(true);
        player.prepareAsync();

    }
    public void setList(ArrayList<Song> theSongs){
          valuesList=theSongs;
        }

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

    public void setSong(int songIndex)
    {
          songPosn=songIndex;
    }

    @Override
    public void onPrepared(MediaPlayer mp) 
    {
        // TODO Auto-generated method stub
         mp.start();        
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        // TODO Auto-generated method stub

    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        // TODO Auto-generated method stub
        return false;
    }



}

ListActivity(用户从此处选择歌曲):

 public class ListMusic extends Activity implements OnItemClickListener
 {

  private static ArrayList<Song> valuesList;
private ListView list;
private MySongsAdapter songAdt;
private static MusicService MusicService;
private Intent playIntent;
private static boolean musicBound=false;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_music);

    list = (ListView)findViewById(R.id.song_list);
    valuesList = new ArrayList<Song>();

    getSongList(); //update the valuesList

    songAdt = new MySongsAdapter(this, valuesList);
    list.setAdapter(songAdt);

    list.setOnItemClickListener(this);


}

//connect to the service

public static ServiceConnection musicConnection= new ServiceConnection()
{

  @Override
  public void onServiceConnected(ComponentName name, IBinder service) 
  {
    MusicBinder binder = (MusicBinder)service;
    //get service
    MusicService = binder.getService();
//  Toast.makeText(getApplicationContext(), "Music Service Is Not Null", Toast.LENGTH_LONG).show();
    //pass list
    MusicService.setList(valuesList);
    musicBound = true;
  }

  @Override
  public void onServiceDisconnected(ComponentName name) {
    musicBound = false;
  }
};      
@Override
protected void onStart() 
{
    //
  super.onStart();
  Toast.makeText(getApplicationContext(), "Start", Toast.LENGTH_LONG).show();


  if(playIntent ==null)
  {
    playIntent = new Intent(this, MusicService.class);
    bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE);
    startService(playIntent);
  }

}

public void songPicked(View view, int position)
{
    //כאשר שיר נבחר
    MusicService.setSong(position);
    MusicService.playSong();
}

public void getSongList() 
{ 
    //אחזור רשימת השירים מהמכשיר
  ContentResolver musicResolver = getContentResolver();
  Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
  Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null);

  long thisId;
  int titleColumn, idColumn, artistColumn;
  String thisTitle, thisArtist;

  if(musicCursor!=null && musicCursor.moveToFirst())
  {
      //get columns
      titleColumn = musicCursor.getColumnIndex
        (android.provider.MediaStore.Audio.Media.TITLE);
      idColumn = musicCursor.getColumnIndex
        (android.provider.MediaStore.Audio.Media._ID);
      artistColumn = musicCursor.getColumnIndex
        (android.provider.MediaStore.Audio.Media.ARTIST);
      //add songs to list

      while (musicCursor.moveToNext())
      {
        thisId = musicCursor.getLong(idColumn);
        thisTitle = musicCursor.getString(titleColumn);
        thisArtist = musicCursor.getString(artistColumn);
        valuesList.add(new Song(thisId, thisTitle, thisArtist));
      }

    }

}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
        long id)
{
     //באירוע של לחיצה על שיר
    songPicked(view, position);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) 
{
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.music, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected (MenuItem item) 
{
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.

        int id= item.getItemId();
        switch(id)
        {
        case R.id.btnExit:
              stopService(playIntent);
              MusicService=null;
            finish();
              break;

        }
        return true;

}

与MainActivity的连接:

   playIntent = new Intent(this, MusicService.class);
    bindService(playIntent, ListMusic.musicConnection,    Context.BIND_AUTO_CREATE);
       startService(playIntent);

拜托,如果有人知道这是什么问题,我将不胜感激! 谢谢你的到来。

1 个答案:

答案 0 :(得分:0)

  

我希望音乐能够在所有活动中继续进行,因此每次取消绑定服务可能会出现问题。

这只是一个问题,因为你这样做

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

现在,每次调用unbindService()时,音乐都会停止。可以在活动的unbindService()onDestroy()中调用onPause(),但是您不应该停止播放服务中的onUnbind()方法。< / p>

您可以为服务提供一个公共静态方法,当您需要停止音乐时,可以调用该方法:

@Override
public boolean onUnbind(Intent intent)
{
     return false;
}

public static void stopPlayMusic()
{
     player.stop();
     player.release();
}

通过这种方式,即使某些内容与您的服务无关,音乐也会继续播放,同时还有一种方法可以停止播放音乐。为了使这项工作,您还必须使player成为静态变量。