android Binder机制

一、Bindr框架

Binder是一种架构,这种架构提供了服务器端口、Binder驱动、客户端接口三个模块。如下图:


客户端:客户端通过Ixxx.Stub.asInterface()来获得代理,同时将BinderProxy传给Proxy对象,其中BinderProxy即为要获得的mRemote。

Binder驱动:通过获得的mRemote引用,调用transact()方法,向远程服务发送消息,并挂起当前线程等待服务端处理,服务端处理完后,返回消息。

Binder服务端:当获得Binder驱动发送的消息,调用onTransact()来处理,将处理结果返回给Binder驱动。

从以上可以看出,客户端通过Binder驱动的中转,然后调用远程服务的Binder。即在整个过程中,存在两个Binder,一个是服务端的Binder,另一个是驱动中的Binder对象。

二、Service

1.客户端如何获得服务端的Binder对象

首先,当调用binderService(Intentservice,ServiceConnection conn,int flags),启动服务时,服务器端启动一个Binder对象,通过Service的onBinder()方法获得,最终会调用ServiceConnection的onServiceConnected(ComponentNamename,IBinder service),其中参数service是一个IBinder对象,其实的得到的是一个BinderProxy对象,当使用上述步骤时,最终能够在客户端的任何地方调用远程服务。

2.aidl

aidl文件的语法基本类似java,需要注意的是,只能写入以下三种类型

(1)      java的原子类型,如int,long,String等

(2)      Binder引用

(3)      实现了Parcelable的对象

   aidl文件会自动生成一个java文件,该java文件主要完成三个任务。

(1)      定义一个Java interface,该类基于IInterface接口,提供函数asBinder().

(2)      定义一个Proxy类,该类将作为客户端访问服务端的代理。

(3)      定义一个Stub类,这是一个abstract类,基于Binder类,并且实现(1)中的接口,主要有服务端来使用。

三、一个远程调用的例子

场景:模拟WmS(IWindowManager,IWindowSession,IWindow),客户端通过IWindowManager获得远程连接,然后在客户端获得IWindowSession,客户端通过它调用远程服务,同时客户端将自身的IWindow对象通过IWindowSession传给服务端,然后服务端通过IWindow对象来回调客户端。

实现:三个aidl文件:IStockQuoteService.aidl,IHM.aidl,IClient.aidl,和上述场景对应。

IStockQuoteService.aidl

package com.hm.service;

import com.hm.service.IHM;
import com.hm.service.IClient;

interface IStockQuoteService
{
    double getQuote(String ticker);
    IHM getIHM();
    void setClient(IClient client);
}

IHM.aidl

package com.hm.service;

import com.hm.service.IClient;

interface IHM {
String getName();
void setClient(IClient client);
}

IClient.aidl

package com.fx.hm.service;

interface IClient
{
    String getClassName();
}

在服务端实现IStockQuoteService: StockQuoteServiceImpl

public class StockQuoteServiceImpl extends IStockQuoteService.Stub
	{
		IClient mClient;
		public double getQuote(String ticker) throws RemoteException {
			Log.e(TAG,"getQuote() called for "+ticker);
			return 20;
		}

		public IHM getIHM() throws RemoteException {
			return new HM(this);
		}

		public void setClient(IClient client) throws RemoteException {
			// TODO Auto-generated method stub
			mClient = client;
			Log.e("service", mClient.getClassName());			
		}		
	}

在服务端实现IHM:HM

import android.os.RemoteException;

import com.hm.service.IClient;
import com.hm.service.IHM;

public class HM extends IHM.Stub
{
	IStockQuoteService mService;	
	HM(IStockQuoteService service)
	{
		mService  = service;
	}

	public String getName() throws RemoteException {
		return mService.toString();
	}

	public void setClient(IClient client) throws RemoteException {
		mService.setClient(client);
	}
}

在客户端实现IClient:


private IClient mClient = new IClient.Stub() {		
		public String getClassName() throws RemoteException {
			return MainActivity.this.toString();
		}
	};

调用过程:

首先调用binderService(intent,conn,flags),

在ServiceConnection的onServiceConnected(name,service)方法中获得代理:

IStockQuoteServicemService = IStockQuoteService.Stub.asInterface(service);

IHM ihm =mService.getHM();

ihm.setClinet(mClient);



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值