Android中的Binder机制

一、kernel层

1.binder_init

  1. 分配内存
  2. 初始化设备
  3. 放入链表

2.binder_open

  1. 创建binder_proc结构体并分配内存
  2. 将当前进程的信息放到binder_proc
  3. binder_proc放进procs链表中
  4. 将当前binder_proc放入fileprivate_data指针中

3.binder_mmap

  1. 定义了传输的内容不可超过4M
  2. 根据用户空间的虚拟内存大小,分配一块大小相同的内核空间
  3. 分配一块物理空间(大小为4K),并将这块空间映射到用户空间和内核空间
  4. buffer插入空闲列表中

4.binder_ioctl

  1. 一进来先有一个中断
  2. switch(cmd),一般是binder_write_read

5.binder_write_read

  1. 先有一个copy_from_user,这里不是copy的有效命令,是先copy的头部信息
  2. 然后会根据write和read的size,判断是读还是写

二、ServiceManager的启动过程

启动过程要从Zygote的启动过程开始说起,当从init进程中fork出一个子进程,并且 调用Runtime.start() 方法后,在AppRuntimestart方法中会启动、注册jni方法,并启动ZygoteInitmain方法。
而在注册jni方法中,会将binder相关的东西注册进去。
在init进程解析init.rc文件时,会启动ServiceManager,对应service_manager.c中的main方法。

ServiceManager的main方法

  1. 打开binder驱动,并完成映射
  2. binder_become_context_manager,注册成为上下文管理者
  3. binder_loop,循环等待客户端的请求

1.open_binder

打开一个大小为128K的binder

2.binder_become_context_manager

  1. 创建一个新的node
  2. 设置成为上下文管理者

3.binder_loop

  1. 写入bc_enter_loop指令
  2. 循环处理

三、ServiceManager的获取

获取SM的两种情况:(1)将服务注册到SM中 (2)获取服务

1. IServiceManager.cpp中的defaultServiceManager()方法

代码如下所示:

sp<IServiceManager> defaultServiceManager()
{
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;

    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == NULL) {
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }

    return gDefaultServiceManager;
}
  1. 保证了单例
  2. ProcessState是进程唯一的,表示进程的状态。 ProcessState::self():
    在ProcessState的Self中,会调用自身的构造函数,在构造函数中,会做几件事情:
    1. 打开binder设备,设置服务的最大线程数目为15个
    2. 用mmap做内存映射(大小为1M-8K
  3. ProcessState->getContextObject:
    sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
    {
    return getStrongProxyForHandle(0);
    }
    

四、服务的注册:以AMS为例

1.SystemServer中

  1. 在SystemServer的run()方法中,会先创建SystemrServiceManager,然后会启动三类服务.
  2. startBootStrapServices()方法中,关键代码有
      ...
      //这一句会启动ActivityManagerService
      mActivityManagerService = mSystemServiceManager.startService(
              ActivityManagerService.Lifecycle.class).getService();
      mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
      mActivityManagerService.setInstaller(installer);
      ...
      //这里会调用ServiceManager.addService()方法
      mActivityManagerService.setSystemProcess();
      ...
    
    这里做两件事:
    1. 启动并返回AMS
    2. 调用AMS的setSystemProcess方法
      然后在setSystemProcess中,会调用SM的addService方法,方法如下:
  3. SeriviceManager.addService():
    public static void addService(String name, IBinder service, boolean allowIsolated) {
        try {
        //这是关键代码
            getIServiceManager().addService(name, service, allowIsolated);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }
    
    1. 分开看:getIServiceManager()
      1.  private static IServiceManager getIServiceManager() {
         if (sServiceManager != null) {
           return sServiceManager;
         }
        
           // Find the service manager
           //BinderInternal.getContextObject会创建一个BpBinder,并将BpBinder与BinderProxy绑定在一起,返回的是BinderProxy
            
           // ServiceManagerNative.asInterface()返回的是ServiceManagerProxy
           sServiceManager = ServiceManagerNative
              .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
         return sServiceManager;
        }
        
      2. 然后看:addService()

五、服务的获取:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值