栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

binder系统分层

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

binder系统分层

binder系统回顾
在binder的应用程序中,他会涉及3个应用程序,如下图所示:

如上所示,这三个程序分别为server,service_manager,client。一般流程如下:

server:
	1.通过addservice(“heelo”,xxx),添加服务。
	2.server的内核空间,驱动生成一个对应的binder_node节点,binder_node中存在两个成员,分别为ptr,cokie,对于每个服务,该值的设定都不一样,后续根据这两个值区分服务。
	12.接收到client数据之后,读取,解析,处理,然后分局收到的ptr,cokie调用对应函数。

service_manager:
	3.驱动收到到添加服务之后,会在service_manager的内核空间创建一个binder_ref,其中存在node与desc两个成员。node指向binder_node,desc=1表示这是第一个服务。
	4.service_manager的用户空间会创建一个surinfo链表,其中每个节点存在成员name与handle,如图这里为name=“hello”,handle等于其内核态的desc。
	7.接收到client发送的hello,在surinfo链表中查找,可以获得对应的handle值。
	8.驱动根据handle值,找到对应的binder_ref,创建一个client的binder_ref,回复给给client。

client:
	5.通过getservice(“hello")获得服务,sm通过hello名字在service_manager的用户空间的surinfo找到其对应的handle。
	6.sm根据handle值,在驱动层找到相应的binder_ref,发给client进程,创建client进程的biander_ref,node指向server中的服务,把binder_ref.desc返回给用户空间。
	10.返回desc给client的用户空间,即getservice(“hello")返回是一个new BpBinder(handle)。
	11.使用服务:首先构造数据,然后向handle=1发送数据,驱动程序根据handle=1找到binder_ref,根据binder_ref.proc找到server,然后发送数据给对应的server。

从上面可以看出,binder系统是非常的复杂的,所以会分成好几个层次,比如写应用程序的人,其只要写出应用程序就可以了,对于进程之间的通信,由binder驱动的系统工程师编写,现在我们讲解bander系统的分成。
Binder系统分层
其可以分为3个层次如下图:

binder系统可以分为服务层,RPC(远程调用),IPC(进程通信)3个层次。
第一层为服务层
我们打开之前边写的C++程序,test_client.cpp。可以看到:

int main(int argc, char **argv)
	sm->getService(String16("goodbye"));
	service->saygoodbye();

第二层为RPC(远程调用)
实现RPC的文件为BpGoodbyeService.cpp,其中实现了sayhello与sayhello_to两个函数。其主要是构造数据发送数据,打开BpGoodbyeService.cpp:

void saygoodbye(void)
	{
		

        Parcel data, reply;
        data.writeInt32(0);

        remote()->transact(GOODBYE_SVR_CMD_SAYGOODBYE, data, &reply);
	}
	
	int saygoodbye_to(const char *name)
	{
		
        Parcel data, reply;

        data.writeInt32(0);
        data.writeString16(String16(name));

        remote()->transact(GOODBYE_SVR_CMD_SAYGOODBYE_TO, data, &reply);

		return reply.readInt32();
	}

其工作很简单,就是构造数据之后,通过remote()->transact函数发送数据。最终导致BnHelloService.cpp中对应的onTransact被调用,然后解析再区分调用的对应的函数。

第三层为IPC(进程通信)
其remote()->transact如何发送数据,BnHelloService如何接受数据,怎么调用到服务的onTransact函数?
我们知道remote()得到一个Bpbinder对象,我们进入Bpbinder.cpp找到transact函数:

status_t BpBinder::transact(
	status_t status = IPCThreadState::self()->transact(mHandle, code, data, reply, flags);

我们在看看test_server.cpp:

int main(void)
	
	IPCThreadState::self()->joinThreadPool();

这个循环一直等待接受数据。

使用c++实现一个服务,除了IPC层不需要编写,其他的都需要我们编写。如果我们使用java编写,则只需要实现服务层即可。

java实现
打开我们之前编写的java程序,TestClient.java:

public static void main(String args[])
	IBinder binder = ServiceManager.getService("hello");
	IHelloService svr = IHelloService.Stub.asInterface(binder);
	svr.sayhello();

可以知道TestClient只需要获取服务,然后调用即可。
其具体实现为HelloService.java:

public class HelloService extends IHelloService.Stub {
    public void sayhello() throws android.os.RemoteException {
    public int sayhello_to(java.lang.String name) throws android.os.RemoteException {	

看起来我们似乎直接通过客户端调用服务端的函数。其实他们是用过RPC层实现的,其为IHelloService.java,该为自动生成文件。其中:

public interface IHelloService extends android.os.IInterface
    public static abstract class Stub extends android.os.Binder implements IHelloService
		public Stub()
android.os.RemoteException;
	    public static IHelloService asInterface(android.os.IBinder obj)
	    @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
	    @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
	    private static class Proxy implements IHelloService
	    	@Override public void sayhello() throws android.os.RemoteException
	    		 mRemote.transact(Stub.TRANSACTION_sayhello, _data, _reply, 0);
	    	@Override public int sayhello_to(java.lang.String name) throws android.os.RemoteException
	    		mRemote.transact(Stub.TRANSACTION_sayhello_to, _data, _reply, 0);
	public void sayhello() throws android.os.RemoteException;
    public int sayhello_to(java.lang.String name) throws 

其上发送数据是类Proxy,接收数据的函数是onTransact,onTransact中会分别去调用的具体函数。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/276614.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号