android bind service 学习笔记

        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 (){

	@Override
	public void onServiceConnected(ComponentName name, IBinder service) {
		// TODO Auto-generated method stub
	}

	@Override
	public 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 block
				e.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());
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return 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 (){

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// TODO Auto-generated method stub
			mMessenger=new Messenger(service);//用service中返回的binder构建实例
			send.setEnabled(true);
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			mMessenger=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() {
		
		@Override
		public void showResult(){
			// TODO Auto-generated method stub
		//Toast.makeText(AidlService.this, "the toast show from AidlService", Toast.LENGTH_LONG).show();
			Log.d("remoteservice","showResult");
		}
	};
	@Override
	public 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(){

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// TODO Auto-generated method stub
			mAidlService=IRemoteService.Stub.asInterface(service);
			Log.d("ConMainActivity", "onServiceConnected");
			try {
				mAidlService.showResult();
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			
		}
		
	};


源码下载地址:稍后奉上










原文地址:https://www.cnblogs.com/javawebsoa/p/3091451.html