皮皮网
皮皮网

【底量图指标源码】【体温上报源码】【秒余源码】binder架构源码_binder源码分析

来源:电子书网站 源码 发表时间:2024-12-22 10:11:28

1.深度分析Binder线程池的架构启动流程
2.一文分析Binder机制和AIDL的理解
3.Android进程间通信之bindService篇
4.Framework层的Binder(源码分析篇)
5.AndroidFramework 之启动 ServiceManager
6.面试中常被问到的Framework 底层原理!

binder架构源码_binder源码分析

深度分析Binder线程池的源码源码启动流程

       理论基础Binder

       Binder它是Android中的一种进程间通信机制,它主要采用的分析是CS架构模式。Binder框架中主要涉及到4个角色Client、架构Server、源码源码ServiceManager及Binder驱动,分析底量图指标源码其中Client、架构Server、源码源码ServiceManager运行在用户空间,分析Binder驱动运行在内核空间。架构

线程池

       线程池它是源码源码一种用于多线程处理形式,处理过程中将任务添加到队列,分析然后在创建线程后自动启动这些任务。架构线程池线程都是源码源码后台线程。每个线程都使用默认的分析堆栈大小,以默认的优先级运行,并处于多线程单元中。

       简单的说:线程池就是创建一些线程,它们的集合称为线程池。

Binder线程池启动流程

       我们知道一个新的app应用程序进程在创建完成之后,它会通过调用RunTimeInit类的静态成员函数zygoteInitNative来进行启动Binder线程池。

       Binder线程池启动过程中,主要调用几个关键函数:ZygoteInitNative--->onZygoteInit--->startThreadPool。

       下面的源码分析主要是以android5.0版本为例。

ZygoteInitNative源码分析

       由于ZygoteInitNative函数是体温上报源码java实现的代码,实践上最终调用的是由C++实现的JNI方法。以下代码来源于系统的/frameworks/base/core/jni/androidRuntime.cpp文件中

staticvoidcom_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv*env,jobjectclazz){ //gCurRuntime是个全局的变量,后面跟上的是另外实现的方法。gCurRuntime->onZygoteInit();}onZygoteInit源码分析

       onZygoteInit函数在需要源码的位置:/frameworks/base/cmds/app_process/app_main.cpp文件中。

该函数是个虚函数,并且是一个无返回值和无参数的函数virtualvoidonZygoteInit(){ //Re-enabletracingnowthatwe'renolongerinZygote.atrace_set_tracing_enabled(true);//获取进程的状态信息sp<ProcessState>proc=ProcessState::self();//打印日志信息ALOGV("Appprocess:startingthreadpool.\n");//启动线程池proc->startThreadPool();}startThreadPool源码分析

       startThreadPool系统实现在\frameworks\native\libs\binder\ProcessState.cpp文件中。

       每一个支持Binder进程间通信机制的进程内都有一个唯一的ProcessState对象,当这个ProcessState对象的成员函数StartThreadPool函数被第一次调用的时候,它就会在当前进程中启动一个线程池,并将mThreadPoolStarted这个成员变量设置为true。

//该函数是个无参数,无返回值的函数voidProcessState::startThreadPool(){ AutoMutex_l(mLock);//判断线程池是否启动状态,启动的话就将标志信息设置为true属性。if(!mThreadPoolStarted){ mThreadPoolStarted=true;spawnPooledThread(true);}}总结

       Binder在android底层中是一个非常重要的机制,我们在实际的项目调用过程中,我们在app应用程序中只要实现自己的Binder本地对象的时候,跟其他服务一样,只需要将它进行启动起来,并且进行注册到ServerMananger就可以了。至于内部的实现一般是不需要去关心的。

一文分析Binder机制和AIDL的理解

       理解Android进程间通信的关键在于Binder机制,这是Android系统用于不同进程间交互的基础。不理解此机制,阅读源码时会面临诸多困难,秒余源码难以把握系统深层次的逻辑与实现。尤其在遇到复杂问题时,深入理解进程间通信原理至关重要。

       Binder机制的引入主要是为了弥补Linux进程中其他通信方式在性能与安全性方面的不足。尽管Binder并非Android的原创技术,其源自更早的OpenBinder项目,但它已经成为Android进程间通信的核心手段。Binder机制通过代理对象实现进程间的数据交换,确保跨进程操作的高效与安全。

       在Android中,Binder代理是进程间通信的桥梁。当两个应用或进程需要交互时,它们之间不能直接通信,而必须通过Binder实现。同样,应用调用系统服务时,也需通过Binder进行跨进程通信。常见的系统服务如ActivityManagerService(AMS)、WIFI、定位、媒体服务等,都需要通过Binder机制与应用进程交换信息。

       Binder本身是一个实现IBinder接口的Java类,它并非底层驱动,投票评分源码而是Android系统各层通信代码的集合。要理解Binder机制,需要从底层驱动到应用层逐步剖析,耐心分析其代码结构。

       理解AIDL的关键在于其如何简化进程间通信的复杂性。尽管AIDL与实现进程间通信无关,它通过生成的代码模板减少了开发者的负担,降低了出错概率。通过对比使用AIDL与不使用AIDL实现的进程间通信代码,可以更清晰地理解AIDL生成的类是如何构建客户端与服务端之间的桥梁。

       实现进程间通信的示例代码展示了一个简单的客户端和服务端应用。在不使用AIDL的情况下,客户端通过直接调用IBinder对象的transact方法实现通信,这直接展示了Binder通信的核心逻辑。而在使用AIDL的情况下,客户端与服务端通过生成的类实现通信,AIDL生成的Stub类与Proxy类简化了这一过程,使得客户端更容易地与服务端交互,而服务端通过实现Stub类中的方法处理通信请求。

       总结来说,理解AIDL是为了更高效、更简洁地实现进程间通信,而Binder机制则是Android系统实现这一目标的核心技术。通过深入理解这两个组件,压缩图 源码开发者可以更有效地与系统交互,提升应用的性能与稳定性。

Android进程间通信之bindService篇

       在Android的进程间通信中,binder是一种核心机制,广泛应用于四大组件之一的Service。本文专注于使用Service与binder结合的bindservice通信方式,探讨其实现方法与关键特性。

       创建Service作为服务端,其主要功能是向客户端提供接口。创建Service的方式包括扩展binder类、使用Messenger和AIDL。扩展binder类适用于服务端与客户端在同进程场景,不具备跨进程能力,因此这里不详细说明。使用Messenger能实现跨进程通信,特点是请求放入队列,服务端无需线程安全设计,但在实际项目中使用较少。

       AIDL(Android Interface Definition Language)是一种便捷实现跨进程通信的工具。它支持客户端并发访问,要求服务端实现线程安全设计。创建.aidl文件定义接口,服务端和客户端均需包含源码。实现AIDL接口的实例在onBind()接口返回给客户端,使得客户端能调用接口。

       使用AIDL的关键技术点在于通过IPC调用传递对象。支持Java语言原语类型、String、CharSequence、List和Map等数据类型传递。对于自定义对象,必须实现Parcelable接口,以完成序列化。在Android 及以上版本中,可直接定义Parcelable对象。AIDL工具在编译时协助生成序列化代码。

       在方法中使用Bundle参数时,需在解析前显式设置ClassLoader。这样能确保Bundle中对象正确加载。

       本文总结了使用binder和bindservice实现Java端与Java端跨进程通信的方式,并简单概述了AIDL工具的关键技术点。使用bindservice结合AIDL,能在多个场景下有效实现Java应用之间的高效通信。

Framework层的Binder(源码分析篇)

       本文以android-.0.0_r的AOSP分支为基础,解析framework层的Binder工作原理。

       从ServiceManager的getService方法入手,其核心代码是通过getIServiceManager().getService(name)获取服务。首先,ServiceManager的实现与进程中的ProcessState密切相关,ProcessState是单例,负责打开和映射Binder驱动。构造函数中,它会初始化驱动、验证版本并设置线程数,接着进行binder映射。

       在ProcessState的getContextObject方法中,调用native函数android_util_Binder.cpp中的getContextObject()。这个函数通过handle 0(ServiceManager的handle)获取BpBinder对象,然后通过javaObjectForIBinder函数将其转换为Java中的类型。

       进一步分析,BpBinder与java层的Binder之间存在对应关系,通过BinderProxy NativeData创建单例的BinderProxy。然后,每个服务的BinderProxy实例化和计数处理都在这个过程中完成。ServiceManagerNative.asInterface方法简化了getIServiceManager的调用,通过调用asInterface实例化ServiceManagerProxy。

       IServiceManager接口通过AIDL生成,其代理类ServiceManagerProxy实际上是不必要的。aidl文件在编译时生成对应java代码,用于binder通信。通过aidl文件,我们可以看到如queryLocalInterface等方法的实现细节。

       在Parcel的协助下,客户端与服务端进行数据传递,通过序列化和反序列化进行交互。在transact函数中,对Parcel大小进行检查,避免数据传输过大导致的问题。最后,客户端与binder驱动的通信过程涉及了Transaction数据的写入、等待响应、数据处理和内存回收等步骤。

       总的来说,framework层的Binder工作涉及服务管理、数据转换、通信协议和内存管理等环节,理解这些有助于深入掌握Binder的工作机制。

AndroidFramework 之启动 ServiceManager

        本文源码基于 Android ,涉及相关源码如下。

        ServiceManagaer 是 Binder 的守护进程,在 Binder 机制中起着重要的作用。本文将从源码的角度对其进行分析,整体流程如下:

        时序图如下。

        先来看看 ServiceManager 是如何启动的:

        在 Zygote 一文中说过, init 进程启动的第二阶段会解析 init.rc 文件。

        在这之后会触发 trigger init 。

        结合 init.rc 看看 action init 做了什么。

        当触发 trigger init 后,会启动 servicemanager 服务,其声明如下。

        对应的执行文件为 /system/bin/servicemanager ,在编译前位于 frameworks/native/cmds/servicemanager 下,来看看 Android.bp 。

        其对应的源码为 service_manager.c 和 binder.c ,入口函数 main() 位于 servicemanager.c 。

        启动完 ServiceManager 后会打开 Binder 驱动。

        在 main() 中首先调用 binder_open() 。

        binder_open() 主要做了如下事情:

        给结构体 binder_state 分配内存。

        系统调用 open() 打开 /dev/binder ,如果打开驱动失败,则执行 fail_open 释放内存。

        简单的解释一下什么是系统调用?

        由于需要限制不同的程序之间的访问能力,防止程序获取别的程序的内存数据, CPU 划分出两个权限等级,用户态和 内核态。

        所有的用户程序都是运行在用户态,但有时需要做一些内核态的事情,而唯一可以做这些事情的就是操作系统,所以程序需要向操作系统发起请求,以程序的名字来执行这些操作。这时就需要一个从用户态切换到内核态但不能控制内核态中执行的机制,这种机制就是 系统调用。

        系统调用 ioctl() 传入 BINDER_VERSION 命令获取 Binder 驱动版本,对比版本是否一致,不一致则执行 fail_open 释放内存。

        系统调用 mmap() 映射 kb 的内存空间,即把 Binder 驱动文件的 kb 映射到内存空间供 ServiceManager 使用,内存映射失败则执行 fail_map ,关闭 fd 并释放内存。

        ServiceManager 进程 mmap 的内存大小可以通过 adb shell 命令查看。

        可以看到内存映射地址为 0xff ~ 0xf ,差为 0x 即十进制的 kb 。

        打开 Binder 驱动后会将 ServiceManager 设置为上下文管理者。

        调用 binder_become_context_manager() 。

        android 新增 BINDER_SET_CONTEXT_MGR_EXT 命令来设置安全的上下文管理者,如果设置失败,则使用原有的 BINDER_SET_CONTEXT_MGR 命令来设置上下文管理者,两者区别在于是否携带参数。

        最后会进入循环,从 Binder 驱动读取和解析数据。

        调用 binder_loop() 进入循环,不断地通过系统调用 ioctl() 从 Binder 驱动读取数据,并通过 binder_parse() 进行数据解析。

        注意这里调用 binder_loop() 传入的 svcmgr_handler() ,后面会使用到。

        binder_write() 会封装 struct binder_write_read ,并通过系统调用 ioctl() 将对应的命令传递给 Binder 驱动。

        binder_parse() 用来解析从 Binder 驱动读取到的数据,然后根据不同的命令执行对应的操作。

        因为 cmd 命令可能有多个,所以通过 while 循环每次处理一个 cmd 命令,多 cmd 的结构大致如下图所示。

        这里重点看下 BR_TRANSACTION 命令。

        BR_TRANSACTION 是 Binder 驱动向 Server 端发送请求数据。

        binder_transaction_data 的结构如下,其表明了 transcation 传输的具体语义,语义码记录在 code 中,不同语义码携带的数据是不同的,这些数据由 data 指定。

        在解析完 binder_transaction_data 的具体语义后,会调用前面传给 binder_loop() 的 svcmgr_handler() ,其实就是 switch case 语义码做不同的事情。

        ServiceManager 的功能其实很简单:

        至此 ServiceManager 就分析完了。

面试中常被问到的Framework 底层原理!

       Android 开发领域对技术的要求日益提高,不再局限于对四大组件和基础开发技能的了解。现在的公司更加注重候选人的技术深度和对源码原理的理解,尤其在大型企业的面试中,对 Android Framework 底层原理的考察尤为突出。

       Android 的进程通信机制主要通过 Binder 实现,而线程通信则依赖于 Handler。这两个机制不仅是 Android 开发的基石,也是面试中的重要知识点。

       以 Handler 为例,了解其源码结构有助于深入理解相关概念。

       Binder 作为 Android 的主要跨进程通信方式,包括 BinderProxy、BpBinder 等多种实体,以及 ProcessState、IPCThreadState 等封装。它贯穿 Java、Native 层,涉及用户态、内核态,与 Service、AIDL 等紧密相关,向下则与 mmap、Binder 驱动设备相连,是一个庞大而复杂的机制。

       面试中,面试官可能会问及基于 mmap 的拷贝实现方式。通过图形化解释,我们可以更好地理解这一过程:Client 和 Server 处于不同进程,拥有不同的虚拟地址规则,无法直接通信。通过映射页框,可以将物理内存分别与 Client 和 Server 的虚拟内存块进行映射,实现一次数据拷贝。

       精通 Framework 不仅需要对底层原理有深入了解,还需要将 Framework 知识应用于实践,如 Android App 的启动机制、AMS、PMS、WMS 等。

       许多学习者和实践者在 Android Framework 面临困扰,但很少人能够逆向分析并找到最优解决方案。Framework 是 Android 开发的深水区,也是衡量程序员能力的重要标准。

       为了帮助大家节省学习周期,我整理了《Android Framework 源码解析》这份文档,希望对大家在技术道路上有所帮助。完整版文档已在 GitHub 收录,请参考学习。

相关栏目:百科