binder机制原理分析(二):普通Service注册到ServiceManager

本文深入解析Android Binder机制原理,包括ServiceManager进程启动、Service注册、获取服务等关键步骤,阐述Binder线程池创建与交互流程。

binder机制原理分析一共分5个部分,其实省了一点,但是分析到后面都差不多了,以后再补充吧。

1、ServiceManager 进程启动

2、普通Service注册到ServiceManager

3、从ServiceManager中获取服务

4、java层service的注册过程

5、Java层service的获取过程

一般service注册到ServiceManager都经过五个步骤:

  1. sp proc = (ProcessState::self());获取ProcessState实例;
  2. sp sm = defaultServiceManager();获取IServiceManager实例;
  3. XXXService::Instantiate();调试用addService方法,将XXX服务注册到sm中去;
  4. ProcessState::self()—>startThreadPool();开启binder线程池;
  5. IPCThreadState::self()—>joinThreadPool();添加到binder线程池;
    获取ProcessState实例

涉及到的关键类:

IServiceManager:重写了addServie、gerService、checkService、serviceList四个方法
ProcessState:1、构造中open_driver();mmap();2、getContextObj方法获取ServiceManager类;3、startThreadPool开启线程池new poolThread
IPCThreadState:1、transact方法输入入口;2、writeTransactionDate()方法数据,将数据封装成binder_transact_date并写入到mOut中;3、执行waitForResponse方法等待响应结果。4、joinThreadPool加入到线程池中并开启do while与binder交互;5、执行talkWithDriver方法,将数据封装成binder_write_read通过ioctl的BINDER_WRITE_READ指令发送给binder驱动;6、通过executeCommand方法执行binder响应指令BP_XXX。7、IPCThreadState中还包含mIn、一个mOut,其中mIn用来接收来自Binder驱动的数据,mOut用来存储发往Binder驱动的数据,它们默认大小都为256字节

步骤一、ProcessState::self()

获取processState单例

是个单例通过autoLock自锁,返回一个new ProcessState实例对象;ProcessState中定义了binder默认内存大小是1M-8K;默认binder的最大线程数是15。
注意: 这里的binder默认的内存大小和binder的默认最大线程数大小

#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))
#define DEFAULT_MAX_BINDER_THREADS 15
sp<ProcessState> ProcessState::self()
{
   
   
    Mutex::Autolock _l(gProcessMutex);
    if (gProcess != NULL) {
   
   
        return gProcess;
    }
    gProcess = new ProcessState;
    return gProcess;
}

进行processState构造

1、调用open_driver()方法,其实就是调用open()方法获取proc结构体,同时获取binder版本号并设置最大线程数;2、通过mmap()申请虚拟内存空间并进行双映射。

ProcessState::ProcessState()
1open_driver()中调用open()方法获取proc结构体,同时获取binder版本号和binder最大线程数
    mDriverFD(open_driver())
.................{
   
   
    if (mDriverFD >= 0) {
   
   
.................
2、通过mmap机制申请虚拟空间内存并进行双映射
        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
    }
}

步骤二、获取SM对象defaultServiceManager()

  1. 通过defaultServiceManager()方法——>调用ProcessState中的getContextObject()方法——>调用getStrongProxyForHandler(0)——>最终获得BpBinder实例。
  2. 通过interface_cast(new BpBinder(0))模板宏定义替换INTERFACE标签,实现asInterface方法后得到BpServiceManager(new BpBinder(0))。这里的BpServiceManager属于IServiceManager,BpServiceManager继承了BpRefBase,BpRefBase中的成员mRemote指针指向BpBinde(0)。
  3. IServiceManager实现了IInterface的addService、getService、checkService和serviceList四个方法。所以BpServiceManager也实现了。

先获取BpBinder(0)

sp<IServiceManager> defaultServiceManager(){
   
   
        if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
        {
   
   
            AutoMutex _l(gDefaultServiceManagerLock);
            // 循环获取servicemanager,采用循环应该是考虑到servicemanager进程可能加载慢的问题
            while (gDefaultServiceManager == NULL) {
   
   
                gDefaultServiceManager = interface_cast<IServiceManager>(
                    ProcessState::self()->getContextObject(NULL));
                if (gDefaultServiceManager == NULL)
                    sleep(1);
            }
        }
        return gDefaultServiceManager;
    }
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/){
   
   
返回handle = 0即servicemanager代理的强引用
    return getStrongProxyForHandle(0);
}
获取handle对应的BpBinder对象。
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle){
   
   
    sp<IBinder> result;
    AutoMutex _l(mLock);
    handle_entry* e = lookupHandleLocked(handle);
    if (e != NULL) {
   
   
        IBinder* b = e->binder;
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
   
   
            if (handle == 0) {
   
   
                // 查询servicemanager是否可用
                Parcel data;
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, NULL, 0);
                if (status == DEAD_OBJECT)
                   return NULL;
            }
            // 创建handle对应的BpBinder对象,并返回
            b = new BpBinder(handle);
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值