一、在activity当中调用Service中的方法
例如,我现在写的音乐播放器的的例子,播放音乐,暂停音乐,下一首等待都是在Service类中实现的,而我要控制音乐播放的情况只能在activity中,这时候就要在activity当中调用Service中的方法。
通过bindService方法,我们可以得到绑定后返回的Service的实例,分为两步:
1) 在Service类中重写onBind方法
继承Binder的内部类,可以通过里面的方法得到Service实例
class PlayBinder extends Binder { public PlayService getPlayService(){ return PlayService.this; } }
@Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. return new PlayBinder();//返回这个内部类 }
2) 在Activity中
private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) {//IBinder service就是Service返回的Binder对象PlayService.PlayBinder binder = (PlayService.PlayBinder) service;//实例化内部类playService = binder.getPlayService();//调用内部类方法,得到Service实例 } @Override public void onServiceDisconnected(ComponentName name) { playService = null; } };
//绑定服务 public void bindPlayService(){ if (!isBound){ Intent intent = new Intent(this,PlayService.class); bindService(intent,conn, Context.BIND_AUTO_CREATE); isBound = true; } }这样就可以通过playService调用Service中的方法了
二、如何在Service当中调用Activity的方法呢?
还是音乐播放器的例子,这是在Service当中播放音乐,播放音乐的进度只有在Service当中可以得到,但是我们需要把播放音乐的进度显示当Activity中的UI组件上,这就涉及到在Service中调用Activity的方法
1)首先在Service中,
定义一个内部接口,并且定义没有实现的方法,如下
//更新状态的接口 public interface MusicUpdateListener{ public void onPublish(int progress); public void onChange(int position); }同时声明一个这个接口的对象,并且生成对应的setter方法
MusicUpdateListener musicUpdateListener;public void setMusicUpdateListener(MusicUpdateListener musicUpdateListener) { this.musicUpdateListener = musicUpdateListener; }2)在Activity中,实例化一个这个接口的对象,并且实现里面的方法private PlayService.MusicUpdateListener musicUpdateListener = new PlayService.MusicUpdateListener() { @Override public void onPublish(int progress) { publish(progress); } @Override public void onChange(int position) { change(position); } };用上面的方法在Activity得到Service的实例后,调用它的setMusicUpdateListener方法,把这个实例化后的接口对象设置进去
playService.setMusicUpdateListener(musicUpdateListener);上面这句话一般在声明ServiceConnection时就直接实现了,如下:private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { PlayService.PlayBinder binder = (PlayService.PlayBinder) service; playService = binder.getPlayService(); //这样就在Activity中实现了PlayService中的内部接口,从而在PlayService中调用里面的方法实现对Activity组件的操作 playService.setMusicUpdateListener(musicUpdateListener); } @Override public void onServiceDisconnected(ComponentName name) { playService = null; } };这时,在Service当中就可以直接通过内部接口对象调用里面的方法了,从而达到了在Service当中控制Activity组件的方法了。