2017-04-25 133 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()中使用了日誌消息,並且當我再次運行該應用程序時我得到了它。