bind service可以实现应用组件绑定本地的service,也可以绑定其他应用的service,在android中每个

应用运行在自己的虚拟机中,每个虚拟机对应linux内核中一个进程,所以绑定其他应用的service,可以实

现进程间通信。

binder是能进行远程操作的对象的一个基类,一个轻量级的远程过程调用机制,核心部分在IBinder类

中定义。这个类是一个IBinder类的实现,为创建一个本地实现对象提供了标准的支持,后面的绑定都是

基于binder来实现。

绑定本地的service并与之交互相对比较简单,在service中创建一个binder实例,此实例中需要有一个

public方法可供绑定者调用,在此public 方法中返回service实例,这样就可以调用service中的public方法

了。binder实例通过onBind回调方法返回给绑定者:

public class LocalService extends Service {    private final IBinder mBinder = new LocalBinder();    private final int mserviceparam=10; public class LocalBinder extends Binder {        LocalService getService() {            // Return this instance of LocalService so clients can call public methods            return LocalService.this;        }    }    @Override    public IBinder onBind(Intent intent) {        return mBinder;    }    /** method for clients */    public int getServiceParem(){      return mserviceparam;        }}
绑定service通过以下方法实现:

bindService (Intent service, ServiceConnection conn, int flags)
ServiceConnection类中有两个回调方法,当service绑定成功后和取消绑定会调用这两个方法:

private ServiceConnection mConnection=new ServiceConnection (){@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {// TODO Auto-generated method stub}@Overridepublic void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stub}};

绑定不同应用的service并与之交互,需要借助其他的类来实现,有两种方式:messenger 、aidl

1.messenger 中文翻译“信使”,负责信息的发送,可以跨进程,

messenger有两个构造函数:

a . public Messenger (Handler target)

handler是用来处理Messenger发送过来的message,

即一个Messenger会有一个Handler与之相对应,

通过Messenger.getBinder()获得一个binder对象,在service的onBind()方法中返回给客服端

public class MyService extends Service{ static final int MSG_SEND_FROM_REMOTE=1; static final int MSG_SEND_FROM_LOCAL=2; static final int MSG_RELY_FROM_SERVICE=3; class IncomingHandler extends Handler{  public void handleMessage(Message msg){ switch(msg.what){ case MSG_SEND_FROM_REMOTE: Toast.makeText(getApplicationContext(),"hello,i am from remote,send content is"+msg.getData().getString("sendContent"), Toast.LENGTH_LONG).show(); try {msg.replyTo.send(Message.obtain(null, MSG_RELY_FROM_SERVICE, null));} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();} break; case MSG_SEND_FROM_LOCAL: Log.d("remoteservice", "MSG_SEND_FROM_LOCAL"); Toast.makeText(getApplicationContext(),"hello,i am from local", Toast.LENGTH_LONG).show(); break;     default: super.handleMessage(msg); } }  } final Messenger mMessenger=new Messenger(new IncomingHandler());@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn mMessenger.getBinder();}}

b. public Messenger (IBinder target)

此构造函数一般用于绑定Service的组件中, 传入的binder对象是从service返回的,这样此Messenger

就会与service中的messenger相对应,用此Messenger发送消息,在service中可以接受到,并做相应处理。

到此我们只实现了从绑定组件发送消息到service,service不能发送消息给绑定组件,

如要实现双向通信,则需要在绑定组件中再创建一个Messenger对象,用public Messenger (Handler target)

构造方法,把此Messenger赋值给msg.replyTo,一并发送到service中,service用此Messenger发送消息给

绑定组件

private ServiceConnection mConnection=new ServiceConnection (){@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {// TODO Auto-generated method stubmMessenger=new Messenger(service);//用service中返回的binder构建实例send.setEnabled(true);}@Overridepublic void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stubmMessenger=null;send.setEnabled(false);}};
class incomingHandler extends Handler{ //构建绑定组件的handler,service发送过来的message在此处理public void handleMessage(Message msg){switch(msg.what){case MSG_RELY_FROM_SERVICE:sendcontent.setText("service received");break;default:super.handleMessage(msg);}}}
private Messenger reMessenger=new Messenger(new incomingHandler());//构建绑定组件的Messenger

private void sendMessage() throws RemoteException{//发送消息Message msg=Message.obtain(null, MSG_SEND_FROM_REMOTE, null);Bundle data=new Bundle();data.putString("sendContent",sendcontent.getText().toString());msg.setData(data);msg.replyTo=reMessenger;mMessenger.send(msg);Log.d("remoteservice", "sendMessage");}

2.AIDL android interface definition language 接口定义语言,

src/ 目录中创建一个以.aidl为后缀名的接口定义文件,android SDK工具会自动在 gen/ 目录中创建

名字一样的java文件,java文件是一个Ibinder接口文件。

如定义的.aidl文件为:

package txj.remoteservice;interface IRemoteService {      void showResult();}
会自动生成一个.java 文件:

/* * This file is auto-generated.  DO NOT MODIFY. * Original file: E:\\android\\newworkspase\\RemoteService\\src\\txj\\remoteservice\\IRemoteService.aidl */package txj.remoteservice;public interface IRemoteService extends android.os.IInterface{/** Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implements txj.remoteservice.IRemoteService{private static final java.lang.String DESCRIPTOR = "txj.remoteservice.IRemoteService";/** Construct the stub at attach it to the interface. */public Stub(){this.attachInterface(this, DESCRIPTOR);}/** * Cast an IBinder object into an txj.remoteservice.IRemoteService interface, * generating a proxy if needed. */public static txj.remoteservice.IRemoteService asInterface(android.os.IBinder obj){if ((obj==null)) {return null;}android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);if (((iin!=null)&&(iin instanceof txj.remoteservice.IRemoteService))) {return ((txj.remoteservice.IRemoteService)iin);}return new txj.remoteservice.IRemoteService.Stub.Proxy(obj);}@Override public android.os.IBinder asBinder(){return this;}@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException{switch (code){case INTERFACE_TRANSACTION:{reply.writeString(DESCRIPTOR);return true;}case TRANSACTION_showResult:{data.enforceInterface(DESCRIPTOR);this.showResult();reply.writeNoException();return true;}}return super.onTransact(code, data, reply, flags);}private static class Proxy implements txj.remoteservice.IRemoteService{private android.os.IBinder mRemote;Proxy(android.os.IBinder remote){mRemote = remote;}@Override public android.os.IBinder asBinder(){return mRemote;}public java.lang.String getInterfaceDescriptor(){return DESCRIPTOR;}@Override public void showResult() throws android.os.RemoteException{android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);mRemote.transact(Stub.TRANSACTION_showResult, _data, _reply, 0);_reply.readException();}finally {_reply.recycle();_data.recycle();}}}static final int TRANSACTION_showResult = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);}public void showResult() throws android.os.RemoteException;}

其中的stub抽象内部类继承了binder和实现了自己定义的接口
在service中需创建一个类extends Stub 并实现自己定义的接口方法,在onbind()方法中返回一个

此类的对象。

public class AidlService extends Service {     private IRemoteService.Stub mbindder=new IRemoteService.Stub() {@Overridepublic void showResult(){// TODO Auto-generated method stub//Toast.makeText(AidlService.this, "the toast show from AidlService", Toast.LENGTH_LONG).show();Log.d("remoteservice","showResult");}};@Overridepublic IBinder onBind(Intent intent) {// TODO: Return the communication channel to the service.return mbindder;} public void onDestroy(){ Log.d("remoteservice","onDestroy");  super.onDestroy(); }}    

把此.aidl文件复制到需要绑定此服务的应用的src/ 文件目录中(包名也要一样),也会在gen/中自动生成

相对应的java文件。

绑定组件在绑定成功后会得到service返回的binder,通过下面方法得到自己定义接口类型的对象,即可

调用service中实现的方法:mAidlService=IRemoteService.Stub.asInterface(service);

实现代码:

private ServiceConnection mAidlConnection=new ServiceConnection(){@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {// TODO Auto-generated method stubmAidlService=IRemoteService.Stub.asInterface(service);Log.d("ConMainActivity", "onServiceConnected");try {mAidlService.showResult();} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();}}@Overridepublic void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stub}};

源码下载地址:

http://download.csdn.net/detail/txj8612/5423099










更多相关文章

  1. Android(安卓)apiDemo 学习——对话框AlertDialogSamples
  2. [置顶] [Android(安卓)Studio 权威教程]最实用的快捷键
  3. Android中View更新方法Invalidate()和postInvalidate()
  4. android 选项卡TabHost
  5. Android中Intent,service,broadcast应用浅析(一)
  6. Android之-异步消息处理机制
  7. android 获取屏幕高度和宽度 的方法
  8. Android前台画面和后台service之间通信的方法之Broadcast
  9. Android(安卓)Activity间传递自定义类的对象

随机推荐

  1. Android混合开发(二)——JSBridge传值注意
  2. 转: [Android]获取未安装的APK信息
  3. android 自适应 多屏幕支持 .
  4. Android(安卓)之 使用MediaPlayer播放音
  5. 68.android 简单的布局展示不全的问题,明
  6. Android的Activity屏幕切换动画(二)-左右
  7. Android(安卓)build system ---转
  8. Android(安卓)SQLite增删改查基本用法,通
  9. Android中Bitmap的剪切与拉伸
  10. android surfaceflinger研究----Surface