Android Binder进程间通信-ServiceManager代理对象的获取过程

本文主要是介绍Android Binder进程间通信-ServiceManager代理对象的获取过程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章来源:http://www.itnose.net/detail/6043249.html
更多文章:http://www.itnose.net/type/85.html

一、测试代码:

       ~/Android/external/binder/server

        ----FregServer.cpp

        ~/Android/external/binder/common

        ----IFregService.cpp

        ----IFregService.h

       ~/Android/external/binder/client

       ----FregClient.cpp

 

       Binder库(libbinder)代码:

       ~/Android/frameworks/base/libs/binder

       ----BpBinder.cpp

       ----Parcel.cpp

       ----ProcessState.cpp

       ----Binder.cpp

       ----IInterface.cpp

       ----IPCThreadState.cpp

       ----IServiceManager.cpp

       ----Static.cpp

       ~/Android/frameworks/base/include/binder

       ----Binder.h

       ----BpBinder.h

       ----IInterface.h

       ----IPCThreadState.h

       ----IServiceManager.h

       ----IBinder.h

       ----Parcel.h

       ----ProcessState.h

 

        驱动层代码:

       ~/Android//kernel/goldfish/drivers/staging/android

       ----binder.c

       ----binder.h

 

二、源码分析

      1、程序首先开始从Service进程FregServer.cpp的main函数开始执行

     ~/Android/external/binder/server

     ----FregServer.cpp

 

class FregService : public BnFregService
{...........
public:static void instantiate(){defaultServiceManager()->addService(String16(FREG_SERVICE), new FregService());}...........
};int main(int argc, char** argv)
{FregService::instantiate();ProcessState::self()->startThreadPool();IPCThreadState::self()->joinThreadPool();return 0;
}
      main函数首先调用静态方法instantiate,在instantiate中调用了defaultServiceManager(), defaultServiceManager()函数实现如下:

 

     

      ~/Android/frameworks/base/libs/binder

      ----IServiceManager.cpp

 

sp<IServiceManager> defaultServiceManager()
{if (gDefaultServiceManager != NULL) return gDefaultServiceManager;//如果已经创建了代理对象,那么就直接返回{AutoMutex _l(gDefaultServiceManagerLock);//使用锁,来实现单例模式if (gDefaultServiceManager == NULL) {gDefaultServiceManager = interface_cast<IServiceManager>(//分三步获取Service Manager代理对象ProcessState::self()->getContextObject(NULL));}}return gDefaultServiceManager;
}
      其中gDefaultServiceManagerLock,gDefaultServiceManager都定义在Static.cpp中。

 

       ~/Android/frameworks/base/libs/binder

       ----Static.cpp

 

Mutex gDefaultServiceManagerLock;   //锁
sp<IServiceManager> gDefaultServiceManager; //IServiceManager的强指针
       全局变量 gDefaultServiceManager是一个类型为IServiceManager的强指针,它指向进程内的一个BpServiceManager对象,即Service Manager代理对象;而全局变量gDefaultServiceManagerLock是用来保证一个进程至多只有一个Service Manager代理对象。结合锁机制来保证对象在进程中的唯一性,这是单例设计模式的经典实现。

 

       如果已经创建了代理对象,那么就直接返回。如果没有创建,那么分三步创建:

       (1)、调用ProcessState类的静态成员函数self获取进程内的一个ProcessState对象。

       (2)、调用前面获得的ProcessState对象的成员函数getContextObject创建一个Binder代理对象

       (3)、调用模板函数interface_cast<IServiceManager>将前面获得的Binder代理对象封装成一个Service Manager代理对象。

 

        2、调用ProcessState类的静态成员函数self获取进程内的一个ProcessState对象

       ~/Android/frameworks/base/libs/binder

       ----ProcessState.cpp

 

sp<ProcessState> ProcessState::self()
{if (gProcess != NULL) return gProcess;//如果已经创建了,就直接返回AutoMutex _l(gProcessMutex);if (gProcess == NULL) gProcess = new ProcessState;//创建ProcessState对象return gProcess;
}
      其中gProcess,gProcessMutex都位于Static.cpp中

 

 

Mutex gProcessMutex;
sp<ProcessState> gProcess;
      全局变量gProcess是一个类型为ProcessState的强指针,它指向进程内的一个ProcessState对象;而全局变量gProcessMutex是一个互斥锁,是用来保证一个进程至多只有一个ProcessState对象的,同样是一个单例模式。

 

 

      首次进入,故创建ProcessState对象。

 

      ~/Android/frameworks/base/libs/binder

      ----ProcessState.cpp

 

ProcessState::ProcessState(): mDriverFD(open_driver()), mVMStart(MAP_FAILED).....
{if (mDriverFD >= 0) {...........// mmap the binder, providing a chunk of virtual address space to receive transactions.mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);...........
}
     在初始化构造函数中调用了open_driver方法。

 

      ~/Android/frameworks/base/libs/binder

      ----ProcessState.cpp

 

static int open_driver()
{if (gSingleProcess) {return -1;}int fd = open("/dev/binder", O_RDWR);//又一个进程打开了设备文件,binder_procs又多了一个进程的结构体if (fd >= 0) {fcntl(fd, F_SETFD, FD_CLOEXEC);int vers;
#if defined(HAVE_ANDROID_OS)status_t result = ioctl(fd, BINDER_VERSION, &vers);
#elsestatus_t result = -1;errno = EPERM;
#endifif (result == -1) {LOGE("Binder ioctl to obtain version failed: %s", strerror(errno));close(fd);fd = -1;}if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {LOGE("Binder driver protocol does not match user space protocol!");close(fd);fd = -1;}
#if defined(HAVE_ANDROID_OS)size_t maxThreads = 15;result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);if (result == -1) {LOGE("Binder ioctl to set max threads failed: %s", strerror(errno));}
#endif} else {LOGW("Opening '/dev/binder' failed: %s\n", strerror(errno));}return fd;
}
      open_driver首先调用了open打开设备文件,在http://blog.csdn.net/jltxgcy/article/details/25797011这盘文章中已经讲解了驱动层的binder_open所做的事。然后的调用ioctl传入BINDER_VERSION参数来获取vers。最后调用ioctl传入BINDER_SET_MAX_THREADS参数来设备该进程所支持的最大线程数。

 

     

      在初始化列表中调用mmap把设备文件/dev/binder映射到进程的地址空间,其实将/dev/binder映射到进程的地址空间实际上是请求Binder驱动程序为进程分配内核缓冲区。


      3、调用前面获得的ProcessState对象的成员函数getContextObject创建一个Binder代理对象

      ~/Android/frameworks/base/libs/binder

      ----ProcessState.cpp

 

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
{if (supportsProcesses()) {return getStrongProxyForHandle(0);} else {return getContextObject(String16("default"), caller);}
}

 

这篇关于Android Binder进程间通信-ServiceManager代理对象的获取过程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/944797

相关文章

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

作业提交过程之HDFSMapReduce

作业提交全过程详解 (1)作业提交 第1步:Client调用job.waitForCompletion方法,向整个集群提交MapReduce作业。 第2步:Client向RM申请一个作业id。 第3步:RM给Client返回该job资源的提交路径和作业id。 第4步:Client提交jar包、切片信息和配置文件到指定的资源提交路径。 第5步:Client提交完资源后,向RM申请运行MrAp

高效+灵活,万博智云全球发布AWS无代理跨云容灾方案!

摘要 近日,万博智云推出了基于AWS的无代理跨云容灾解决方案,并与拉丁美洲,中东,亚洲的合作伙伴面向全球开展了联合发布。这一方案以AWS应用环境为基础,将HyperBDR平台的高效、灵活和成本效益优势与无代理功能相结合,为全球企业带来实现了更便捷、经济的数据保护。 一、全球联合发布 9月2日,万博智云CEO Michael Wong在线上平台发布AWS无代理跨云容灾解决方案的阐述视频,介绍了

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

[Linux]:进程(下)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:Linux学习 贝蒂的主页:Betty’s blog 1. 进程终止 1.1 进程退出的场景 进程退出只有以下三种情况: 代码运行完毕,结果正确。代码运行完毕,结果不正确。代码异常终止(进程崩溃)。 1.2 进程退出码 在编程中,我们通常认为main函数是代码的入口,但实际上它只是用户级

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动