- 浏览: 20200 次
- 性别:
- 来自: 北京
最新评论
由代码来补充部分:
int main(int argc, char** argv)
{
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p", sm.get());
AudioFlinger::instantiate();
MediaPlayerService::instantiate();
CameraService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
sp<ProcessState> proc(ProcessState::self()),这一行代码会建立ProcessState对象,一个进程只有唯一的一个ProcessState对象,而ProcessState类的作用是来打开/dev/binder设备。这也就说明了一个问题,一个进程只不可能同时存在多个对/dev/binder的操作。
sp<IServiceManager> sm = defaultServiceManager(),这一行代码要做的事情参见上图。1、创建一个BpBinder。2、由BpBinder对象创建BpServiceManger对象。(为什么要采取如此不自然的方式,可以看一下这两个对象继承的基类)。完成这一步骤的最重要的作用在于以后对于IServiceManager对象的方法的调用,都将会由其子类BpServiceManger的方法来实现(这样做的意义何在?这样的作用仅仅在于我们可以重用IServiceManager的代码,别忘了我们还有一个类似的继承自IServiceManager的类,它叫做BnServiceManger)。这样说起来似乎过于抽象,好在我们可以举一个例子,接下去的代码就会有例子出现。
CameraService::instantiate(),这一行的代码(前面还有两行?相信我,他们绝对是几乎一样的实现,当然我是指从Binder层来说,而不是指与硬件相关的交互)。我们仍然先画出结构图:
我们需要一点代码来辅助我们的分析,CameraService::instantiate的代码如下:
void CameraService::instantiate() {
defaultServiceManager()->addService(
String16("media.camera"), new CameraService());
}。
仍然是由defaultServiceManager函数开始,但是我们此时已经拥有了对象,而这样做的目的仅仅在于我们调用的会是BpServiceManger类中的addService方法,而不是IServiceManager基类的addService方法。我们试着去寻找BpServiceManger类中的addService函数。在此之前有个需要我们注意的地方new CameraService,这里实例化了一个CameraService对象,他的基类们是我们要注意的,因为之后我们将不得不关注于整套虚函数调用的机制。CameraService类的继承关系我在图中已经画出:IBinder->BBinder(ICmaerService两个基类)->BnInterface->BnCamerService->CamerService,看起来足够复杂,不幸的是这个继承模式是有意义的。
我们将思路再拉回来,接着看BpServiceManger类中addService的实现:
virtual status_t addService(const String16& name, const sp<IBinder>& service)
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readInt32() : err;
}
Data.writeInterfaceToken与data.writeString这两行我们无需关注,因为它们完成一些接口命名之类的事情。来看看data.writeStrongBinder会做些什么:
status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
{
return flatten_binder(ProcessState::self(), val, this);
}
而flatten_binder代码如下:
status_t flatten_binder(const sp<ProcessState>& proc,
const sp<IBinder>& binder, Parcel* out)
{
flat_binder_object obj;
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
if (binder != NULL) {
IBinder *local = binder->localBinder();
if (!local) {
BpBinder *proxy = binder->remoteBinder();
if (proxy == NULL) {
LOGE("null proxy");
}
const int32_t handle = proxy ? proxy->handle() : 0;
obj.type = BINDER_TYPE_HANDLE;
obj.handle = handle;
obj.cookie = NULL;
} else {
obj.type = BINDER_TYPE_BINDER;
obj.binder = local->getWeakRefs();
obj.cookie = local;
}
} else {
obj.type = BINDER_TYPE_BINDER;
obj.binder = NULL;
obj.cookie = NULL;
}
return finish_flatten_binder(binder, obj, out);
}
我们先来关注IBinder *local = binder->localBinder()这一行代码,binder变量是一个IBinder类的指针,那么是否是说我们要调用的是IBinder类的localBinder函数呢?我去查看代码,发现它是一个虚函数,说明我们将会调用的是指针指向的对象的localBinder函数。还没忘记我们刚才特别提到的地方吧?defaultServiceManager()->addService(String16("media.camera"), new CameraService());它是一个CamerService对象,理论上来说我们应该是按照沿基类向上的方式查找实现,CamerService-> BnCamerService->BnInterface->ICmaerService,BBinder两个基类-> IBinder这样的查找顺序。我们在BBinder类的实现中找到了这个localBinder这个函数,那么这里将会调用的就是BBinder对象的实现:
BBinder* BBinder::localBinder()
{
return this;
}很明显代码接着会走到橙色部分。
那么finish_flatten_binder又会做些什么呢?代码我就不贴了,它的作用是更新相应的数据偏移量指针。但是写到这里,我们似乎越看越糊涂,这些步骤有什么意义?Parcel类为什么又突然出现了?我们来做一下补充,首先是Parcel类的作用,它是用来完成数据的序列化的,也就是完成数据投递之前的准备工作的。投递的数据都会放在这个类的一个实例中。我去查找Parcel类的定义的时候发现它没有虚函数,也就是说关于投递数据序列化的操作都会在这个类及其实现中完成。我们终于可以暂时的摆脱那些虚函数们了。
我们的工作还远没有结束,我们还没有看到数据是如何投递的?那么我们接着来看addService函数中的最后一个函数调用remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply),它明显是用来投递数据的,如何投递?这里我们要弄清楚两个问题:1、remote函数返回的是什么?也就是transcat是哪个对象的方法。2、transcat如何与底层交互。
我们先来看看第一个问题。先前已经讨论过,addService方法的调用是来自BpServiceManager对象,我们忘了给出另一套类继承的机制:RefBase->IServiceManager,BpRefBase两个基类->BpInterface->BpServiceManager。 那么这里的remote方法(与addService一样均属于BpServiceManager),将会调用BpServiceManager的基类BpRefBase的remote方法。其实现时:inline IBinder* remote() { return mRemote; }。问题在于这里的mRemote会是BBinder呢还是BpBinder?这个讨论使得我们不得不又再次回到之前的代码中去(确实复杂,但还不至于会使人疑惑。)答案在很早以前的defaultServiceManager函数中,之前我们并没有分析过这个函数,是因为我们之前并不需要知道这个函数太多的细节,我们只用知道它是为了完成BpServiceManger对象的建立,但实际上,它还完成了另一个功能,将BpRefBased对象的mRemote成员初始化为BpBinder对象。来看代码:
sp<IServiceManager> defaultServiceManager()
{
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
if (gDefaultServiceManager == NULL) {
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
}
}
return gDefaultServiceManager;
}
ProcessState::self()->getContextObject 此函数返回一个BpBinder对象,当然这个对象的指针是其基类指针IBander。然后由interface_cast再次调用,而为mRemote成员的赋值也同样发生在BpServiceManger对象的建立之时,调用BpServiceManger类的构造函数: BpServiceManager(const sp<IBinder>& impl): BpInterface<IServiceManager>(impl),再次调用BpInterface类的构造函数
template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
: BpRefBase(remote)
就在绿色的代码部分了,具体的分析请看另一篇文档,这里只是补充。
第一个问题,为我们指明了方向,也就是通讯的时候会采用BpBinder对象的transact函数。这样我们来继续看一下第二个问题,现在我们直奔BpBinder类中的transact函数的实现:
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// Once a binder has died, it will never come back to life.
if (mAlive) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
int main(int argc, char** argv)
{
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p", sm.get());
AudioFlinger::instantiate();
MediaPlayerService::instantiate();
CameraService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
sp<ProcessState> proc(ProcessState::self()),这一行代码会建立ProcessState对象,一个进程只有唯一的一个ProcessState对象,而ProcessState类的作用是来打开/dev/binder设备。这也就说明了一个问题,一个进程只不可能同时存在多个对/dev/binder的操作。
sp<IServiceManager> sm = defaultServiceManager(),这一行代码要做的事情参见上图。1、创建一个BpBinder。2、由BpBinder对象创建BpServiceManger对象。(为什么要采取如此不自然的方式,可以看一下这两个对象继承的基类)。完成这一步骤的最重要的作用在于以后对于IServiceManager对象的方法的调用,都将会由其子类BpServiceManger的方法来实现(这样做的意义何在?这样的作用仅仅在于我们可以重用IServiceManager的代码,别忘了我们还有一个类似的继承自IServiceManager的类,它叫做BnServiceManger)。这样说起来似乎过于抽象,好在我们可以举一个例子,接下去的代码就会有例子出现。
CameraService::instantiate(),这一行的代码(前面还有两行?相信我,他们绝对是几乎一样的实现,当然我是指从Binder层来说,而不是指与硬件相关的交互)。我们仍然先画出结构图:
我们需要一点代码来辅助我们的分析,CameraService::instantiate的代码如下:
void CameraService::instantiate() {
defaultServiceManager()->addService(
String16("media.camera"), new CameraService());
}。
仍然是由defaultServiceManager函数开始,但是我们此时已经拥有了对象,而这样做的目的仅仅在于我们调用的会是BpServiceManger类中的addService方法,而不是IServiceManager基类的addService方法。我们试着去寻找BpServiceManger类中的addService函数。在此之前有个需要我们注意的地方new CameraService,这里实例化了一个CameraService对象,他的基类们是我们要注意的,因为之后我们将不得不关注于整套虚函数调用的机制。CameraService类的继承关系我在图中已经画出:IBinder->BBinder(ICmaerService两个基类)->BnInterface->BnCamerService->CamerService,看起来足够复杂,不幸的是这个继承模式是有意义的。
我们将思路再拉回来,接着看BpServiceManger类中addService的实现:
virtual status_t addService(const String16& name, const sp<IBinder>& service)
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readInt32() : err;
}
Data.writeInterfaceToken与data.writeString这两行我们无需关注,因为它们完成一些接口命名之类的事情。来看看data.writeStrongBinder会做些什么:
status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
{
return flatten_binder(ProcessState::self(), val, this);
}
而flatten_binder代码如下:
status_t flatten_binder(const sp<ProcessState>& proc,
const sp<IBinder>& binder, Parcel* out)
{
flat_binder_object obj;
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
if (binder != NULL) {
IBinder *local = binder->localBinder();
if (!local) {
BpBinder *proxy = binder->remoteBinder();
if (proxy == NULL) {
LOGE("null proxy");
}
const int32_t handle = proxy ? proxy->handle() : 0;
obj.type = BINDER_TYPE_HANDLE;
obj.handle = handle;
obj.cookie = NULL;
} else {
obj.type = BINDER_TYPE_BINDER;
obj.binder = local->getWeakRefs();
obj.cookie = local;
}
} else {
obj.type = BINDER_TYPE_BINDER;
obj.binder = NULL;
obj.cookie = NULL;
}
return finish_flatten_binder(binder, obj, out);
}
我们先来关注IBinder *local = binder->localBinder()这一行代码,binder变量是一个IBinder类的指针,那么是否是说我们要调用的是IBinder类的localBinder函数呢?我去查看代码,发现它是一个虚函数,说明我们将会调用的是指针指向的对象的localBinder函数。还没忘记我们刚才特别提到的地方吧?defaultServiceManager()->addService(String16("media.camera"), new CameraService());它是一个CamerService对象,理论上来说我们应该是按照沿基类向上的方式查找实现,CamerService-> BnCamerService->BnInterface->ICmaerService,BBinder两个基类-> IBinder这样的查找顺序。我们在BBinder类的实现中找到了这个localBinder这个函数,那么这里将会调用的就是BBinder对象的实现:
BBinder* BBinder::localBinder()
{
return this;
}很明显代码接着会走到橙色部分。
那么finish_flatten_binder又会做些什么呢?代码我就不贴了,它的作用是更新相应的数据偏移量指针。但是写到这里,我们似乎越看越糊涂,这些步骤有什么意义?Parcel类为什么又突然出现了?我们来做一下补充,首先是Parcel类的作用,它是用来完成数据的序列化的,也就是完成数据投递之前的准备工作的。投递的数据都会放在这个类的一个实例中。我去查找Parcel类的定义的时候发现它没有虚函数,也就是说关于投递数据序列化的操作都会在这个类及其实现中完成。我们终于可以暂时的摆脱那些虚函数们了。
我们的工作还远没有结束,我们还没有看到数据是如何投递的?那么我们接着来看addService函数中的最后一个函数调用remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply),它明显是用来投递数据的,如何投递?这里我们要弄清楚两个问题:1、remote函数返回的是什么?也就是transcat是哪个对象的方法。2、transcat如何与底层交互。
我们先来看看第一个问题。先前已经讨论过,addService方法的调用是来自BpServiceManager对象,我们忘了给出另一套类继承的机制:RefBase->IServiceManager,BpRefBase两个基类->BpInterface->BpServiceManager。 那么这里的remote方法(与addService一样均属于BpServiceManager),将会调用BpServiceManager的基类BpRefBase的remote方法。其实现时:inline IBinder* remote() { return mRemote; }。问题在于这里的mRemote会是BBinder呢还是BpBinder?这个讨论使得我们不得不又再次回到之前的代码中去(确实复杂,但还不至于会使人疑惑。)答案在很早以前的defaultServiceManager函数中,之前我们并没有分析过这个函数,是因为我们之前并不需要知道这个函数太多的细节,我们只用知道它是为了完成BpServiceManger对象的建立,但实际上,它还完成了另一个功能,将BpRefBased对象的mRemote成员初始化为BpBinder对象。来看代码:
sp<IServiceManager> defaultServiceManager()
{
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
if (gDefaultServiceManager == NULL) {
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
}
}
return gDefaultServiceManager;
}
ProcessState::self()->getContextObject 此函数返回一个BpBinder对象,当然这个对象的指针是其基类指针IBander。然后由interface_cast再次调用,而为mRemote成员的赋值也同样发生在BpServiceManger对象的建立之时,调用BpServiceManger类的构造函数: BpServiceManager(const sp<IBinder>& impl): BpInterface<IServiceManager>(impl),再次调用BpInterface类的构造函数
template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
: BpRefBase(remote)
就在绿色的代码部分了,具体的分析请看另一篇文档,这里只是补充。
第一个问题,为我们指明了方向,也就是通讯的时候会采用BpBinder对象的transact函数。这样我们来继续看一下第二个问题,现在我们直奔BpBinder类中的transact函数的实现:
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// Once a binder has died, it will never come back to life.
if (mAlive) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
发表评论
-
服务--Service
2010-09-26 16:07 778Android中的服务和windows ... -
广播接收者(BroadcastReceiver)
2010-09-26 16:05 968广播接收者(BroadcastReceiver) 用于异步接收 ... -
如何安装 Android SDK 和Eclipse 插件
2010-09-21 23:50 2048所需开发环境: JDK 5 或 JDK 6 (仅有JR ... -
Android Service 生命周期
2010-09-19 13:33 1719Android Service 生命周期可以促使移动设备的创新 ... -
Timer和TimerTask详解
2010-09-19 11:09 9451.概览 Timer是一种定时器工具,用来在一个后台线程 ... -
TelephonyManager常用方法
2010-09-19 09:51 1902通过TelephonyManager可以取得手机电信网络的信息 ... -
getSystemService
2010-09-19 09:39 1268getSystemService是Android很 ... -
反编译Android apk文件
2010-09-17 16:02 975找到Android软件安装包中的class.dex: ... -
Grid View
2010-09-17 15:46 1302网格布局:是一个ViewGro ... -
SharedPreferences
2010-09-17 15:04 995SharedPreferences 是以键值对来存储应用程序 ... -
Only the original thread that created a view hierarchy can touch its views<已解决>
2010-09-16 17:32 1979子线程不可以 更新UI主线程 new Thread() { ...
相关推荐
Android系统基于Linux内核,但在进程间通信(IPC)方面并没有采用传统的Linux IPC机制,而是设计并实现了自己的一套轻量级IPC解决方案——Binder机制。该机制不仅提供了高效的进程间通信能力,还为Android框架层提供...
android技术内幕--系统卷,第三章Android的IPC机制,关于Binder通信机制,详细讲解,并附有framework层代码说明,
Android的IPC机制——写的比较深入的文章,详细介绍了binder的原理 work 版
Binder机制由服务端、客户端、以及一个中间代理——Binder驱动共同构成。 二、Binder组件 1. 服务端:通常是一个运行在其他进程的Service,提供接口供客户端调用。 2. 客户端:调用服务端接口的应用程序,位于与...
在Android系统中,Binder机制是实现跨进程通信的关键组件,它允许不同进程间的服务共享和交互。本篇文章主要探讨的是Binder机制中的服务代理对象(Service Proxy Object),特别是BpBinder的核心概念。 首先,服务...
Binder机制是Android系统中核心的进程间通信(IPC)方式,它是一种C/S架构,主要由Client、Server和ServiceManager三部分组成。ServiceManager是Google设计的一段简洁的C代码,它的作用在于集中管理系统的各种服务,...
在Android系统中,Binder机制是实现进程间通信(IPC,Inter-Process Communication)的核心组件。在上一部分我们探讨了C/C++层面的服务代理对象BpBinder以及Binder底层处理方式。现在我们将深入研究Java层面上服务...
### Android进程间通信——Binder机制 #### 一、简要介绍和学习计划 在Android操作系统中,每一个应用程序通常由多个组件如Activity和服务(Service)组成。这些组件可能运行在同一进程中,也可能分布在不同进程中。...
Binder机制基于Client-Server通信模型,这种模型已经在多种平台和应用领域得到广泛使用。在Android系统中,许多功能服务都由不同的Server进程负责提供,而Client进程通过IPC与这些Server进行通信。与传统的IPC通信...
总结来说,“Android Binder简单实例”涉及到Android系统中进程间通信的核心技术——Binder,以及其基本的C/S架构和通信流程。通过学习和分析提供的代码示例,开发者能够更好地理解和掌握Binder在实际应用中的使用。
它是Java层的一部分,与HAL通过Binder机制通信。开发者可以通过`AudioRecord`实例创建并配置一个音频记录会话,指定采样率、位深度、声道数量等参数。同时,`MediaRecorder`类也可以用于录音,提供了更高级别的抽象...
根据之前的博文介绍,《Android系统的Binder机制之二——服务代理对象(1)》,`ProcessState`对象负责管理Service的代理对象,确保进程能够正确地使用Binder机制进行通信。 2. **Service注册**: Mediaserver中...
它通过Binder机制与其他系统服务通信,获取应用信息和用户权限。 3. **编译Android源码**:要编译Android源码,开发者需要搭建AOSP(Android Open Source Project)环境,安装必要的工具如Repo、JDK、NDK等,并执行...
总的来说,"安卓Android源码——电池监控.zip"提供了研究Android电池监控机制的宝贵资源,对于Android开发者尤其是系统级开发者来说,这是一个深入学习和提高的好材料。通过对源码的解析和实践,可以掌握Android系统...
Android系统的许多核心服务如Content Provider、Broadcast Receiver和Service都是通过Binder机制实现的。Binder机制包括客户端(Client)、服务端(Server)和中介(Binder Driver),其中服务端在一个单独的进程中...