Android服务绑定

时间:2017-04-25 05:12:41

标签: android

我有理解绑定到服务的问题 我创造了一个简单的歌曲播放器,提供播放歌曲的服务。 我创建了一个日志来跟踪绑定和解除绑定。 问题是当我退出应用程序时出现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;
    }
}

}

如果有人可以解释

3 个答案:

答案 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时我得到了它。