Android Binder通信学习。

以Hello为例说明设计的几个概念关系:

IhelloService.h : 提供给应用程序使用的类接口,注意是说明服务能够提供的哪些操作接口。

【注意】实际不只是定义一个接口类,还继承该接口并添加虚接口onTransact后定义了一个抽象类BnHelloService

class IHelloService: public IInterface{public:DECLARE_META_INTERFACE(HelloService);   /* 此宏声明了接口IHelloService::getInterfaceDescriptor 和 IHelloService::asInterface(这个接口可以生成一个Bp实例) */virtual void sayhello(void) = 0;virtual int sayhello_to(const char *name) = 0;};class BnHelloService: public BnInterface<IHelloService>{public:virtual status_t    onTransact( uint32_t code,const Parcel& data,Parcel* reply,uint32_t flags = 0);virtual void sayhello(void);virtual int sayhello_to(const char *name);};

BnHelloService.cpp : 为了之后可以用BnHelloService实例化对象,需要对BnHelloService完成接口中定义的虚函数.【这个是实际去干活的服务,’别人‘只是给他发需求】

        status_t BnHelloService::onTransact( uint32_t code,const Parcel& data,Parcel* reply,uint32_t flags){switch (code) {case HELLO_SVR_CMD_SAYHELLO: sayhello();break;case HELLO_SVR_CMD_SAYHELLO_TO: sayhello_to(name8.string());break;}return NO_ERROR;}void BnHelloService::sayhello(void){static int cnt = 0;ALOGI("say hello : %d\n", ++cnt);}int BnHelloService::sayhello_to(const char *name){static int cnt = 0;ALOGI("say hello to %s : %d\n", name, ++cnt);return cnt;}

BpHelloService.cpp : 继承抽象的接口类,并去实现虚函数,这样才能实例化对象,成为给服务发需求的‘别人’。【BpXXService负责给服务发需求,这么说服务并不是谁叫我干活就干,我只听Bp的】

        class BpHelloService: public BpInterface<IHelloService>{public:BpHelloService(const sp<IBinder>& impl): BpInterface<IHelloService>(impl){}void sayhello(void){Parcel data, reply;data.writeInt32(0);data.writeString16(String16("IHelloService"));remote()->transact(HELLO_SVR_CMD_SAYHELLO, data, &reply);}int sayhello_to(const char *name){Parcel data, reply;int exception;data.writeInt32(0);data.writeString16(String16("IHelloService"));data.writeString16(String16(name));remote()->transact(HELLO_SVR_CMD_SAYHELLO_TO, data, &reply);exception = reply.readInt32();if (exception)return -1;elsereturn reply.readInt32();}};IMPLEMENT_META_INTERFACE(HelloService, "android.media.IHelloService");/* 此宏具体实现了接口IHelloService::getInterfaceDescriptor 和 IHelloService::asInterface */

HelloServer.c : 实现的最底层接收请求的服务器,提供怎样的服务呢?只提供这个里面提供的服务BnHelloService!

        int main(void){/* 打开biner并mmap进内存 */sp<ProcessState> proc(ProcessState::self());/* 获得 BnServiceManager */sp<IServiceManager> sm = defaultServiceManager();/* 添加服务 */sm->addService(String16("hello"), new BnHelloService());/* 循环体,不断获取服务并处理 */ProcessState::self()->startThreadPool();IPCThreadState::self()->joinThreadPool();return 0;}

HelloClient.c : 最底层发请求的客户端,这才是满肚子需求的底层人民啊。

        int main(int argc, char **argv){int cnt;/* 打开biner并mmap进内存 */sp<ProcessState> proc(ProcessState::self());/* 获得 BpServiceManager */sp<IServiceManager> sm = defaultServiceManager();/* 获得 根据hello名字 获取服务  */sp<IBinder> binder =sm->getService(String16("hello"));if (binder == 0){ALOGI("can't get hello service\n");return -1;}/* Service肯定是 BpHelloService 指针??* interface_cast<IHelloService>(binder)  ->            IHelloService::asInterface(binder);(IMPLEMENT_META_INTERFACE宏中定义)*【结果:在下面代码中分配一个BpHelloService实例指针】 */sp<IHelloService> service =interface_cast<IHelloService>(binder);/* 调用 BpHelloService提供的函数  */service->sayhello();ALOGI("client call sayhello");return 0;}

好了,下面来总结下:背景是世界的阶级斗争依然是如此的激烈,因此不管干啥我们都分等级,Binder服务也是如此,有需求只向上级反映,由上级出处理:

                BpServiceManager <- HelloClient|\ /BnServiceManager -> HelloServer


Binder的java实现。

IHelloService.aidl : Android接口描述文件,只要用户定义自己需要提供的接口,然后放到frameworks/base/core/java/android/os下,并修改

                        frameworks/base/Android.mk  添加一行core/java/android/os/IHelloService.aidl\
代码:
/** {@hide} */
interface IHelloService
{void sayhello();int sayhello_to(String name);
}

IHelloService.java : 由aidl文件编译出来的接口类,里面除了用户自定义的接口外还包含一个 stub 的内部类。

【stub】:为屏蔽客户调用远程主机上的对象,必须提供某种方式来模拟本地对象,这种本地对象称为存根(stub),根负责接收本地方法调用,并将它们委派给各自的具体实现对象
代码只保留框架:
public interface IHelloService extends android.os.IInterface
{/** Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implements IHelloService{private static final java.lang.String DESCRIPTOR = "IHelloService";/** Construct the stub at attach it to the interface. */public Stub(){this.attachInterface(this, DESCRIPTOR);}/*** Cast an IBinder object into an IHelloService interface,* generating a proxy if needed.*/public static IHelloService asInterface(android.os.IBinder obj){return new IGoodbyeService.Stub.Proxy(obj);  /* 客户端获取服务后,需要转化为proxy才能进行最终的接口调用  */}@Override public android.os.IBinder asBinder(){return this;}/* 实际处理需求的服务端,类似于C++ binder中的BnXxService功能,用于接收需求并实际出执行需求任务 */@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_saygoodbye:{data.enforceInterface(DESCRIPTOR);this.saygoodbye();                      /* 调用本stub中定义的接口函数 */reply.writeNoException();return true;}case TRANSACTION_saygoodbye_to:{data.enforceInterface(DESCRIPTOR);java.lang.String _arg0;_arg0 = data.readString();int _result = this.saygoodbye_to(_arg0);  /* 调用本stub中定义的接口函数 */reply.writeNoException();reply.writeInt(_result);return true;}}}private static class Proxy implements IGoodbyeService  /* 代理类,类似于C++ binder中的BpXxService,用于接收需求并封装数据发生需求给服务端 */{mRemote.transact(Stub.TRANSACTION_saygoodbye_to, _data, _reply, 0);}}public void sayhello() throws android.os.RemoteException;public int sayhello_to(java.lang.String name) throws android.os.RemoteException;
}

Helloservice.java : 服务器代码,非常简单,继承IHelloService.Stub的接口,并实现最终干活的代码。

public class HelloService extends IHelloService.Stub {private static final String TAG = "HelloService";private int cnt1 = 0;private int cnt2 = 0;public void sayhello() throws android.os.RemoteException {cnt1++;Slog.i(TAG, "sayhello : cnt = "+cnt1);}public int sayhello_to(java.lang.String name) throws android.os.RemoteException {cnt2++;Slog.i(TAG, "sayhello_to "+name+" : cnt = "+cnt2);return cnt2;}
}

TestServer.java : 用户这边提供服务的代码,目的就是注册一个服务

public class TestServer {private static final String TAG = "TestServer";public static void main(String args[]){/* add Service */Slog.i(TAG, "add hello service");ServiceManager.addService("hello", new HelloService()); /* 此处添加负责服务器任务的类 */while (true){try {Thread.sleep(100);} catch (Exception e){}}}
}

TestClient.java : 最底层发需求的用户代码。

public class TestClient {private static final String TAG = "TestClient";public static void main(String args[]){/* 1. getService */IBinder binder = ServiceManager.getService("hello");if (binder == null){System.out.println("can not get hello service");Slog.i(TAG, "can not get hello service");return;}IHelloService svr = IHelloService.Stub.asInterface(binder); /* 得到接口的代理 */if (args.length == 1){try {svr.sayhello();System.out.println("call sayhello");Slog.i(TAG, "call sayhello");} catch (Exception e) {}}else{try {int cnt = svr.sayhello_to(args[1]);System.out.println("call sayhello_to "+args[1]+" : cnt = "+cnt);Slog.i(TAG, "call sayhello_to "+args[1]+" : cnt = "+cnt);} catch (Exception e) {System.out.println("call sayhello_to , err :"+e);Slog.i(TAG, "call sayhello_to , err : "+e);}}}
}

Android Binder通信学习相关推荐

  1. Android Binder通信一次拷贝你真的理解了吗?

        Android Binder通信一次拷贝你真的理解了吗? Android Binder框架实现目录: Android Binder框架实现之Binder的设计思想 Android Binder ...

  2. Android Binder机制学习笔记

    声明,学习材料:http://my.unix-center.net/~Simon_fu/?p=875,不是简单的copy 1    Android的进程间通讯机制(IPC)用的是自己的binder机制 ...

  3. Android Binder通信数据结构介绍

    Binder通信进程描述--binder_proc 结构体binder_proc用来描述一个正在使用Binder进程间通信机制的进程.当一个进程调用函数open打开/dev/binder设备文件时,B ...

  4. Android Binder通信机制

    Binder是Android系统进程间通信(IPC)方式之一.Linux已经拥有管道,systemVIPC,socket等IPC手段,却还要倚赖Binder来实现进程间通信,说明Binder具有无可比 ...

  5. Android Binder机制学习总结(二)-Driver部分

    本文主要分析Binder Driver的实现.Binder Driver 的实现代码位于 android kernel中:<kernel>\drivers\staging\android\ ...

  6. 安卓进阶(2)之android Binder通信理解

    关键字 aidl 进程间通信 binder机制 aidl 全名安卓接口定义语言,用于进程间通信.简单理解的话,就是类似应用的服务器和客户端.服务器开启一个服务处理数据,客户端传递数据以及响应回调.具体 ...

  7. Android Binder通信原理(五):Java 端的service 注册和获取

    源码基于:Android R 0. 前言 在阐述相关的知识点,先整理个框架图,后面带着框架图来分析过程: Java 端对于binder 使用大致分为: Java client Java service ...

  8. Android Binder 系统学习笔记(一)Binder系统的基本使用方法

    1.什么是RPC(远程过程调用) Binder系统的目的是实现远程过程调用(RPC),即进程A去调用进程B的某个函数,它是在进程间通信(IPC)的基础上实现的.RPC的一个应用场景如下: A进程想去打 ...

  9. Android binder 框架和学习资料

    1 Android binder 是学习 Android 系统一定要啃得硬骨头,可能你刚开始的时候并不理解其中的精髓,但是在 android 系统的很多地方你都会遇到它. 不过要我自己写明白其中的逻辑 ...

最新文章

  1. activemq 开启监听_ActiveMQ 消息监听 MessageListener 的使用
  2. 廖雪峰python教程pdf-爬虫:把廖雪峰的教程转换成 PDF 电子书
  3. 如何探测浏览器是否开启js功能
  4. C语言的成绩查询系统,c语言 成绩查询系统
  5. ARM GIC简介与Linux中断处理分析
  6. HDU 1559 最大子矩阵
  7. VMWare 虚拟机中安装 CentOS 7
  8. Bootstrap插件之 下拉菜单 源码分析~~
  9. mysql join与where_mysql中left join设置条件在on与where时的用法区别分析
  10. 10款推荐系统模拟器汇总
  11. 高分三号卫星GF-3极化SAR
  12. solidworks动画制作教程——简单直线运动
  13. 如何判断某个类是否有某个注解?
  14. 亚马逊要验证收款查关联?
  15. 你会卖掉自己的网上信息吗?大数据可能根本不属于你
  16. 计算机用户密码怎么查看,电脑密码如何查看? 电脑教程:查看方法
  17. 基于核的黎曼编码和字典学习
  18. 四阶幻方c语言编程,13年 第四届 蓝桥杯C语言C组 第4题 幻方填空
  19. 产学交流 | 重庆师范大学计算机学院、湖北省十堰市竹溪管委会各位专家到访芝诺数据...
  20. 金融风控训练营Task1学习笔记

热门文章

  1. 篱笆家装宝典之三——油漆涂料
  2. C/C++实战——基于Qt框架和visual studio的海康相机SDK二次开发
  3. 斗图还要上微博找资源?微信小程序表情包了解一下
  4. oppo应用市场认领app
  5. [Java基础] 垃圾回收机制
  6. 概率论与数理统计 浙江大学 第54-60讲单元测验
  7. 解决电脑常见问题!五款实用的小众PC软件推荐
  8. Win10下10702060GPU使用Anaconda安装Tensorflow2.3记录
  9. 佳能发布19um像素的全高清视频传感器
  10. 【数据结构】概述 - 逻辑结构与物理结构 - 附练习题