商丘网站建设aliapp,郑州seo课程,wordpress 主题调试,保安公司哪家好一 binder架构原理
Binder是一个类#xff0c;主要用在Service组件应用中。
/framework/base/core/java/Android/os/Binder.java(包含内部类BinderProxy)
client与service分别是不同的进程#xff0c;不能直接通信#xff0c;所以引入BinderDriver
client与service不希望…
一 binder架构原理
Binder是一个类主要用在Service组件应用中。
/framework/base/core/java/Android/os/Binder.java(包含内部类BinderProxy)
client与service分别是不同的进程不能直接通信所以引入BinderDriver
client与service不希望直接与BinderDriver交互所以client端新增proxyservice端新增stub 不希望client端知道binder的存在在client端又引入了manager 最终流程图如下service端的context Manager也就是serviceManager binder相对来说还是比较复杂的有framework层与native层的binder。framework层的binder采用JNI技术来调用native(C/C framework)层的binder架构从而为上层应用程序提供服务。需要注意的是
1 framework层的Binder是建立在Native层架构基础之上的核心逻辑都是交予Native层方法来处理
2framework层的Service Manager类与Native层的功能并不完全对应java层的Service Manager类的实现最终是通过BinderProxy传递给Native层来完成的。 图中红色代表整个framework层binder架构相关组件Binder类代表Server端BinderProxy类代表Client端图中蓝色代表Native层Binder架构相关组件。
1 Binder框架层 a、Native Binder框架层包含以下类(frameworks/native/libs/binder)IInterfaceBnInterfaceBpInterface等。BnInterface继承于BBinder而BpInterface聚合了BpBinder b、Java框架层包含以下类(frameworks/base/core/java/android/os): IBinderBinderIInterfaceServiceManagerNativeServiceManagerBinderInternalIServiceManagerServiceManagerProxy Java框架层的类的部分方法的实现在本地代码里(frameworks/base/core/jni)。2 Binder核心层
Binder核心层主要是IBinder及它的两个子类即BBinder和BpBinder分别代表了最基本的服务端及客户端。源码位于frameworks/native/libs/binder目录下。 binder service服务端实体类会继承BnInterface而BnInterface会继承自BBinder服务端可将BBinder对象注册到servicemananger进程。 客户端程序和驱动交互时只能得到远程对象的句柄handle它可以调用调用ProcessState的getStrongProxyForHandle函数利用句柄handle建立BpBinder对象然后将它转为IBinder指针返回给调用者。这样客户端每次调用IBinder指针的transact方法其实是执行BpBinder的transact方法。
3 binder adapter层 主要是IPCThreadState.cpp和ProcessState.cpp源码位于frameworks/native/libs/binder目录下这两个类都采用了单例模式主要负责和驱动直接交互。 a、ProcessState进程相关的类负责打开binder设备进行一些初始化设置并做内存映射 void ProcessState::startThreadPool()该方法启动的新线程并通过joinThreadPool读取binder设备查看是否有请求。 b、IPCThreadState线程相关的类负责直接和binder设备通信使用ioctl读写binder驱动数据。
4 binder驱动层
Android因此添加了binder驱动其设备节点为/dev/binder主设备号为10binder驱动程序在内核中的头文件和代码路径如下
kernel/drivers/staging/binder.h
kernel/drivers/staging/binder.c
binder驱动层的主要作用是完成实际的binder数据传输。 5 AIDL
基本步骤如下 Client通过ServiceConnection获取到Server的Binder并且封装成一个Proxy。通过Proxy来同步调用IPC方法。同时通过Parcel将参数传给Binder最终触发Binder的transact方法。 Binder的transact方法最终会触发到Server上Stub的onTransact方法。Server上Stub的onTransact方法中会先从Parcel中解析中参数然后将参数带入真正的方法中执行然后将结果写入Parcel后传回。 Client的Ipc方法中执行Binder的transact时是阻塞等待的。一直到Server逻辑执行结束后才会继续执行。当Server返回结果后Client从Parcel中取出返回值实现了一次IPC调用。 AIDL进程通信原理 6 HIDL HIDL 全称为HAL interface definition language发音为“hide-l”是用于指定 HAL 和其用户之间的接口的一种接口描述语言 (IDL)Android O开始引入了HIDL这个概念HIDL和应用层AIDL差不多AIDL常用于连接App和FrameworkHIDL则是用来连接Framework和HALAIDL使用Binder通信HIDL则使用HwBinder通信他们都是通过Binder驱动完成通信只不过两个Binder域不一样。
为什么需要HIDL 目前Android系统生态是几乎每年google都会出一个Android大版本而普通手机用户一部手机一般要用两三年所以你会发现尽管Android系统已经升级到了10马上11出来了然后还是有很多用户依然使用的是Android 567等版本对普通用户来说如果不更换手机就很难跟上Android版本这是因为OEM厂商在同一设备上进行系统升级需要花费时间金钱成本很高导致他们不愿意升级成本高的原因是Android O之前Android Framework的升级需要OEM将HAL也进行对应升级Framework和HAL是一起被编译成system.img它们存在高耦合针对这种情况google在Android O中引入了Treble计划Treble的目的就是解耦Framework和HAL就是通过HIDL来实现Framework不再直接调用HAL而是通过HIDL来间接使用HAL模块每个HAL模块都可以对应一个HIDL服务Framework层通过HwBinder创建HIDL服务通过HIDL服务来获取HAL相关模块继而打开HAL下的设备而最终HAL也从system.img中分离被编进一个单独的分区vendor.img从而简化了Android系统升级的影响与难度。 二 binder用法示例 server端
#include stdio.h
#include sys/stat.h
#include fcntl.h
#include sys/types.h
#include unistd.h
#include stdlib.h
#include sys/mman.h#include utils/RefBase.h
#include binder/IInterface.h
#include binder/Parcel.h
#include utils/threads.h#include cutils/log.h
#include cutils/properties.h
#include binder/IServiceManager.h
#include binder/IPCThreadState.husing namespace android;namespace android
{enum{CALCULATE_MUL_NUM0,CALCULATE_DIV_NUM
};class MyServer:public BBinder
{
public:MyServer();virtual ~MyServer();static int instantiate();virtual status_t onTransact(uint32_t, const Parcel, Parcel*, uint32_t);void parse_edid(void);int DeviceInit(void);void UpdateSurface(void);private:mutable Mutex mLock;
};int MyServer::instantiate()
{int tTempRetdefaultServiceManager()-addService(String16(service.damon), new MyServer());ALOGD(damon server instantiate : %d \n, tTempRet);return tTempRet;
}MyServer::MyServer()
{ALOGD(damon create server !\n);
}MyServer::~MyServer()
{ALOGD(damon destroy server !\n);
}status_t MyServer::onTransact(uint32_t code, const Parcel data, Parcel* reply, uint32_t flags)
{
// ALOGD(damon server onTransact code %d , code);Mutex::Autolock _l(mLock);switch(code){case CALCULATE_MUL_NUM:{int adata.readInt32();int bdata.readInt32();int tTempSuma*b;ALOGD(damon server mul %d %d %d \n, a, b, tTempSum);reply-writeInt32(tTempSum);return NO_ERROR;}break;case CALCULATE_DIV_NUM:{int adata.readInt32();int bdata.readInt32();int tTempSuma/b;ALOGD(damon server div %d %d %d \n, a, b, tTempSum);reply-writeInt32(tTempSum);return NO_ERROR;}break;case 0x10:{}break;default:return BBinder::onTransact(code, data, reply, flags);}return 0;
}
}int main(int argc, char *argv[])
{srand(time(NULL));spProcessState proc(ProcessState::self());spIServiceManager smdefaultServiceManager();ALOGD(damon ServiceManager: %p, sm.get());MyServer::instantiate();ProcessState::self()-startThreadPool();IPCThreadState::self()-joinThreadPool();return 0;
}/
Android.mk文件LOCAL_PATH : $(call my-dir)include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE : false
LOCAL_CFLAGS -O2 -g
LOCAL_SRC_FILES : server.cppLOCAL_SHARED_LIBRARIES libdl libcutils libutils libbinder
LOCAL_C_INCLUDE : $(TOP)/frameworks/base/includeLOCAL_MODULE : server_testLOCAL_MODULE_TAGS: optionalLOCAL_CFLAGS -Wno-unused-parameter -Werrorinclude $(BUILD_EXECUTABLE)client端
#include cutils/log.h
#include cutils/properties.h
#include binder/IServiceManager.h
#include binder/IPCThreadState.husing namespace android;enum{CALCULATE_ADD_NUM0,CALCULATE_SUB_NUM
};enum{CALCULATE_MUL_NUM0,CALCULATE_DIV_NUM
};int main(int argc, char *argv[])
{spIBinder tTempServerBinder;Parcel data, reply;int tTempSum0;ALOGD(damon client main is call .....);spIServiceManager smdefaultServiceManager();while(1){tTempServerBindersm-getService(String16(service.damon));ALOGD(damon client get service : %p, sm.get());if(tTempServerBinder0){ALOGD(damon test service not published, waiting . . .);usleep(1000*1000);continue;}else{ALOGD(damon get service success! );break;}}data.writeInt32(3);data.writeInt32(5);ALOGD(damon create remote !\n);tTempServerBinder-transact(CALCULATE_MUL_NUM, data, reply);tTempSumreply.readInt32();ALOGD(damon client calculate mul num : %d , tTempSum);data.freeData();data.writeInt32(5);data.writeInt32(3);tTempServerBinder-transact(CALCULATE_DIV_NUM, data, reply);tTempSumreply.readInt32();ALOGD(damon client calculate div num : %d \n, tTempSum);return 0;
}Android.mk文件LOCAL_PATH : $(call my-dir)include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE : false
LOCAL_CFLAGS -O2 -g
LOCAL_SRC_FILES : client.cppLOCAL_SHARED_LIBRARIES libdl libcutils libutils libbinder
LOCAL_C_INCLUDE : $(TOP)/frameworks/base/includeLOCAL_MODULE : client_testLOCAL_MODULE_TAGS: optionalLOCAL_CFLAGS -Wno-unused-parameter -Werrorinclude $(BUILD_EXECUTABLE)