绑定服务—与调用者同生死的服务
简单来讲相比于普通service,绑定服务就显得专情多了。。先来一个布局文件
MainActivity的代码如下
public class MainActivity extends Activity { // private MyBinder myBinder;//声明服务的代理对象 private MyBinder myBinder; private boolean bindFlag=false; private static final String TAG = "BindActivity"; private ServiceConnection conn=new ServiceConnection() { //当调用者与服务连接不成功,则回调该方法, 当连接出现异常会回调该方法,假如调用者自己实现的解绑操作,则不会回调该方法 @Override public void onServiceDisconnected(ComponentName name) { Log.v(TAG,"onServiceDisconnected"); bindFlag=false; } /**当调用者与服务连接成功,则回调该方法 * ComponentName: 调用者的组件名 * IBinder: 实现了IBinder接口的对象 ,当要绑定的服务成功回调onBind()方法,则表示绑定成功,即onBind的返回值作为该方法的输入参数 * 通过该IBinder参数来获取服务的实例或者是代理对象 */ @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.v(TAG,"onServiceConnected"); myBinder=(MyBinder) service; //获取代理对象 // myBinder=(IService) service; //获取代理对象 bindFlag=true; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); Log.v(TAG,"onCreate"); } //绑定服务 public void bind(View v){ Log.v(TAG,"bind"); Intent intent=new Intent(this, BindMusic.class); /**绑定服务 * Intent :要绑定的服务的意图描述 * ServiceConnection : 服务连接接口, 调用者和服务 通过这个接口实现通信的,即是调用者与被调用者的桥梁 * 通过这个接口,可以获取服务的实例或者服务的代理对象 * BIND_AUTO_CREATE: 绑定自动创建 */ this.bindService(intent, conn, Context.BIND_AUTO_CREATE); } //解绑服务 public void unbind(View v){ Log.v(TAG,"unbind"); this.unbindService(conn); bindFlag=false;// conn=null; } //播放音乐 public void playmusic(View v){ Log.v(TAG,"playMusic"); if(myBinder!=null){ myBinder.playMusic(); } } //停止音乐 public void stopmusic(View v){ Log.v(TAG,"stopMusic"); if(myBinder!=null){ myBinder.stopMusic(); } } @Override protected void onDestroy() {// if(conn!=null){ // unbindService(conn);// } if(bindFlag){ this.unbindService(conn); } super.onDestroy(); }}
绑定服务的代码
public class BindMusic extends Service { private static final String TAG = "BindMusic"; private MediaPlayer player; // 返回Ibinder对象(把服务的实例或者代理的对象通过Ibinder返回给调用者) @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub Log.v(TAG, "onBind"); return new MyBinder(); } public void closeMusic() { // TODO Auto-generated method stub if (player != null) { player.stop(); player.release(); player = null; } } public void startMusic() { // TODO Auto-generated method stub if (player == null) { player = new MediaPlayer(); try { player.setDataSource( Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath() + "/imissyou.mp3"); player.prepare();// 缓冲 } catch (Exception e) { // TODO: handle exception } } } @Override public void onCreate() { // TODO Auto-generated method stub Log.v(TAG, "oncreat"); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub Log.v(TAG, "onStartCommand"); return super.onStartCommand(intent, flags, startId); } @Override public boolean onUnbind(Intent intent) { // TODO Auto-generated method stub Log.v(TAG, "onUnbind"); return super.onUnbind(intent); } @Override public void onDestroy() { // TODO Auto-generated method stub Log.v(TAG, "onDestroy"); if (player != null) { player.stop(); player.release();// 释放资源 player = null; } super.onDestroy(); } // 返回服务的代理类 ,通过该代理来对外暴露服务的相应方法 public class MyBinder extends Binder { private static final String TAG = "MyBinder"; // 对外暴露 播放音乐的方法 public void playMusic() { Log.v(TAG, "playMusic+IService"); startMusic(); } // 对外暴露停止音乐的方法 public void stopMusic() { Log.v(TAG, "stopMusic+IService"); closeMusic(); } }}
注意要在配置文件中注册绑定服务
面向接口的代理的实现
先定义两个接口Iservice和Iservice2public interface Iservice { public void playMusic(); public void stopMusic() ;}
public interface Iservice2 { public void playMusic(); public void stopMusic() ; public void psuseMusic();}
内部类实现接口的方法
public class MyBinder extends Binder implements Iservice{ private static final String TAG = "MyBinder"; // 对外暴露 播放音乐的方法 public void playMusic() { Log.v(TAG, "playMusic+IService"); startMusic(); } // 对外暴露停止音乐的方法 public void stopMusic() { Log.v(TAG, "stopMusic+IService"); closeMusic(); } }
效果如下