以一个具体的例子,深入剖析一下Android系统的绑定机制
来源:互联网 发布:双肩电脑包 知乎 编辑:程序博客网 时间:2024/04/30 11:48
转自 “http://blog.csdn.net/bigapple88/article/details/6579732
Binder是Android系统中实现进程间通信的核心机制,其本质是一种Proxy模式的具体实现,就像COM,CORBA一样。
Proxy模式的基本思想是客户端程序通过某种方式得到服务器端的代理对象,所有对服务器端的服务请求都发送给该代理对象,该代理对象负责同服务器端进行通信。从客户端的角度看,访问代理对象就如同访问其它本地对象一样;服务器代理对象则屏蔽了所有的进程间通信细节。
本文计划给出一个具体的例子,然后以这个例子为基础,深入剖析一下Android系统的绑定机制。
实例:新增加一个系统服务ExampleService,该服务可以接受一个整形参数,将其值加上100并返回。客户端应用程序使用此服务计算1+100的值。
代码1: 系统服务ExampleService的具体实现
// File: ExampleService.h#ifndef ANDROID_EXAMPLE_SERVICE_H#define ANDROID_EXAMPLE_SERVICE_H#include <utils/threads.h>#include <utils/RefBase.h>#include <binder/IInterface.h>#include <binder/BpBinder.h>#include <binder/Parcel.h>namespace android { class ExampleService : public BBinder { mutable Mutex mLock; int32_t mNextConnId; public: static int instantiate(); ExampleService(); virtual ~ExampleService(); virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t);};}; //namespace#endif
// File: ExampleService.cpp#include "ExampleService.h"#include <binder/IServiceManager.h>#include <binder/IPCThreadState.h>namespace android { static struct sigaction oldact; static pthread_key_t sigbuskey; int ExampleService::instantiate() { LOGE("ExampleService instantiate"); // 调用ServiceManager的addService方法进行系统服务注册,这样客户端程序就可以通过ServiceManager获得此服务的代理对象,从而请求其提供的服务 int r = defaultServiceManager()->addService(String16("byn.example"), new ExampleService()); LOGE("ExampleService r = %d/n", r); return r; } ExampleService::ExampleService() { LOGV("ExampleService created"); mNextConnId = 1; pthread_key_create(&sigbuskey, NULL); } ExampleService::~ExampleService() { pthread_key_delete(sigbuskey); LOGV("ExampleService destroyed"); } // 每个系统服务都继承自BBinder类,都应重写BBinder的onTransact虚函数。当用户发送请求到达Service时,系统框架会调用Service的onTransact函数 status_t ExampleService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { case 0: { pid_t pid = data.readInt32(); int num = data.readInt32(); num = num + 100; reply->writeInt32(num); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } }}; //namespace
# File: Android.mkLOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:= /ExampleService.cppLOCAL_C_INCLUDES := $(JNI_H_INCLUDE)LOCAL_SHARED_LIBRARIES := /libutils libbinderLOCAL_PRELINK_MODULE := falseLOCAL_MODULE := libExampleinclude $(BUILD_SHARED_LIBRARY)
在/framework/android/src/frameworks/base下面新建一个文件夹ExampleService,将以上三个文件复制到该文件夹中。
代码2:启动ExampleService的应用程序
// File: ExampleServer.cpp#include <sys/types.h>#include <unistd.h>#include <grp.h>#include <binder/IPCThreadState.h>#include <binder/ProcessState.h>#include <binder/IServiceManager.h>#include <utils/Log.h>#include <private/android_filesystem_config.h>#include "../ExampleService/ExampleService.h"using namespace android;int main(int argc, char** argv){ sp<ProcessState> proc(ProcessState::self());// 要想使用Binder机制,必须要创建一个ProcessState对象 sp<IServiceManager> sm = defaultServiceManager(); LOGI("ServiceManager: %p", sm.get()); ExampleService::instantiate(); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); return 0;}
# File: Android.mkLOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:= /ExampleServer.cppLOCAL_C_INCLUDES := $(JNI_H_INCLUDE)LOCAL_SHARED_LIBRARIES := /libutils libbinder libExampleLOCAL_PRELINK_MODULE := falseLOCAL_MODULE := ExampleServerinclude $(BUILD_EXECUTABLE)
在/framework/android/src/frameworks/base下面新建一个文件夹ExampleServer,将以上两个文件复制到该文件夹中。
代码3:使用ExampleService的客户端应用程序
// File: Example.h#ifndef ANDROID_BYN_EXAMPLE_H#define ANDROID_BYN_EXAMPLE_Hnamespace android{ class Example { public: void add100(int n); private: static const void getExampleService(); };}; //namespace #endif // ANDROID_BYN_EXAMPLE_H
// File: Example.cpp#include <binder/IServiceManager.h>#include <binder/IPCThreadState.h>#include "Example.h"namespace android{ sp<IBinder> binder; void Example::add100(int n) { getExampleService(); Parcel data, reply; int answer; data.writeInt32(getpid()); data.writeInt32(n); LOGE("BpExampleService::create remote()->transact()/n"); binder->transact(0, data, &reply); answer = reply.readInt32(); printf("answner=%d/n", answer); return; } const void Example::getExampleService() { sp<IServiceManager> sm = defaultServiceManager(); binder = sm->getService(String16("byn.example")); LOGE("Example::getExampleService %p/n",sm.get()); if (binder == 0) { LOGW("ExampleService not published, waiting..."); return; } }}; //namespaceusing namespace android;int main(int argc, char** argv){ Example* p = new Example(); p->add100(1); return 0;}
# File: ExampleLOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:= /Example.cppLOCAL_C_INCLUDES := $(JNI_H_INCLUDE)LOCAL_SHARED_LIBRARIES := /libutils libbinder libExampleLOCAL_PRELINK_MODULE := falseLOCAL_MODULE := Exampleinclude $(BUILD_EXECUTABLE)
在/framework/android/src/frameworks/base下面新建一个文件夹Example,将以上三个文件复制到该文件夹中。
Build整个Android系统,这里一共会在系统中生成三个文件,分别是
/system/lib/libExample.so
/system/bin/ExampleServer
/system/bin/Example
然后启动我们新添加的ExampleService系统服务,并启动客户端程序验证运行结果。
$> adb shell
# cd /system/bin
# ./ExampleServer &
# ./Example
answer=101
在接下来的几篇文章中,我们会以这个例子为基础,深入分析一下Android系统中Binder机制的各个部分。
参考文献:
1. 云中漫步博客:http://my.unix-center.net/~Simon_fu/
2. 如何撰写自己的第一个核心服务--高焕堂:http://www.android1.net/Topic.aspx?BoardID=21&TopicID=990
- 以一个具体的例子,深入剖析一下Android系统的绑定机制
- 深入剖析PHP变量的具体使用方法
- [mfc学习笔记一]以一个CGdiObject类的绘图例子来看一下绘图操作
- 一个ldap身份认证的具体例子
- SVM分类的一个具体例子
- 分析一下前端分页机制的具体实现
- 深入剖析Android系统
- 深入剖析Android系统
- android Parcel的深入剖析
- 深入剖析Android消息机制
- 深入剖析Android消息机制
- 深入剖析Android消息机制
- 深入剖析Android消息机制
- 深入剖析Android消息机制
- 深入剖析Android消息机制
- 深入剖析Android消息机制
- 深入剖析Android消息机制
- 深入剖析Android消息机制
- 找工作
- java 构造函数是如何执行的
- enum singleton
- hdu1867之KMP
- [zz] main函数之前--谁动了我的main
- 以一个具体的例子,深入剖析一下Android系统的绑定机制
- NYOJ 14-会场安排问题
- cygwin的安装中途种种遭遇
- void cdev_init(struct cdev *cdev, const struct file_operations *fops)
- 小米即将完成新一轮融资 传估值近百亿美元
- ubuntu ssh
- hdu_1166 敌兵布阵(树状数组)
- 分割时间段
- 关于 Java 对象序列化您不知道的 5 件事