【试用网站 源码】【iview源码解读】【springmvc源码技巧】zygote源码

1.Android系统启动-SystemServer进程
2.AndroidFramework 之启动 ServiceManager
3.深度分析Binder线程池的源码启动流程
4.Android Framework源码解析,看这一篇就够了

zygote源码

Android系统启动-SystemServer进程

        相关源码文件:

        根据上篇 Android系统启动-Zygote进程

        文章,在Zygote进程启动时,会调用 ZygoteInit.main() 方法,其中分别会调用 registerZygoteSocket、preload 、startSystemServer 、runSelectLoop 来创建服务Socket、提前加载资源、创建SystemServer进程、循环创建子进程。

        本篇文章讲解 startSystemServer() 方法,在startSystemServer()方法中主要完成两件事:

· 创建SystemServer进程

        · SystemServer进程启动系统服务

        下图则是startSystemServer方法的创建过程,先通过 Zygote.forkSystemServe 去创建SystemServer进程,创建SystemServer进程之后,源码通过 handleSystemServerProcess() 在SystemServer进程中去启动服务。

        Zygote.forkSystemServer:

        创建 SystemServer 进程是通过 com.android.internal.os. Zygote 的 nativeForkSystemServer 本地方法创建的,JNI方法的注册在 AndroidRuntime 中,通过查询[包名]_[类名]可以知道对应的方法为:com_android_internal_os_Zygote.cpp类的com_android_internal_os_Zygote_nativeForkAndSpecialize()方法。最后通过 ForkAndSpecializeCommon 方法 fork() 创建SystemServer进程。

        handleSystemServerProcess(parsedArgs)

        通过一连串的分析得知,一是通过 nativeZygoteInit 去启动Bind,二是通过 applicationInit 方法通过异常去反射执行 SystemServer.main 方法,这里为什么需要通过异常去反射执行方法呢?为什么不直接反射执行方法?其实是为了清空栈的信息。到这里并没有启动服务,接下来的 SystemServer.main 方法是启动服务的开始。

        SystemServer.main

        SystemServer执行 main() 方法后调用 run 方法,之后分别调用 startBootstrapServices 、 startCoreServices 、 startOtherServices 开始启动很多服务,像常见的ActivityManagerService、PackageManagerService、WindowManagerService、InputManagerServic服务都在这里开启。

        开启服务有两种方式:

        但是发现最终都是调用到LocalServices.addService这种方法。

        可见启动服务是靠Binder驱动去开启的。

        首先通过JNI的注册方法去创建SystemServer进程,创建进程之后,开始处理SystemServer进程,通过异常反射调用SystemServer的main方法,主要完成两件事:一、启动Binder驱动线程,二、开启服务(AMS、PMS、WMS、IMS等),最后通过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 就分析完了。

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

       理论基础Binder

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

线程池

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

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

Binder线程池启动流程

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

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

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

ZygoteInitNative源码分析

       由于ZygoteInitNative函数是springmvc源码技巧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。

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

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

Android Framework源码解析,看这一篇就够了

       深入解析Android Framework源码,理解底层原理是Android开发者的关键。本文将带你快速入门Android Framework的jdk源码hashmap层次架构,从上至下分为四层,掌握Android系统启动流程,了解Binder的进程间通信机制,剖析Handler、AMS、WMS、Surface、SurfaceFlinger、PKMS、InputManagerService、DisplayManagerService等核心组件的工作原理。《Android Framework源码开发揭秘》学习手册,全面深入地讲解Android框架初始化过程及主要组件操作,适合有一定Android应用开发经验的开发者,旨在帮助开发者更好地理解Android应用程序设计与开发的核心概念和技术。通过本手册的学习,将能迅速掌握Android Framework的关键知识,为面试和实际项目提供有力支持。

       系统启动流程分析覆盖了Android系统层次角度的三个阶段:Linux系统层、Android系统服务层、Zygote进程模型。理解这些阶段的关键知识,对于深入理解Android框架的启动过程至关重要。

       Binder作为进程间通信的重要机制,在Android中扮演着驱动的角色。它支持多种进程间通信场景,包括系统类的打电话、闹钟等,以及自己创建的WebView、视频播放、音频播放、大图浏览等应用功能。

       Handler源码解析,揭示了Android中事件处理机制的核心。深入理解Handler,对于构建响应式且高效的Android应用至关重要。

       AMS(Activity Manager Service)源码解析,探究Activity管理和生命周期控制的原理。掌握AMS的实现细节,有助于优化应用的用户体验和性能。

       WMS(Window Manager Service)源码解析,了解窗口管理、布局和显示策略的实现。深入理解WMS,对于构建美观且高效的用户界面至关重要。

       Surface源码解析,揭示了图形渲染和显示管理的核心。Surface是Android系统中进行图形渲染和显示的基础组件,掌握其原理对于开发高质量的图形应用至关重要。

       基于Android.0的SurfaceFlinger源码解析,探索图形渲染引擎的实现细节。SurfaceFlinger是Android系统中的图形渲染核心组件,理解其工作原理对于性能优化有极大帮助。

       PKMS(Power Manager Service)源码解析,深入理解电池管理策略。掌握PKMS的实现,对于开发节能且响应迅速的应用至关重要。

       InputManagerService源码解析,揭示了触摸、键盘输入等事件处理的核心机制。深入理解InputManagerService,对于构建响应式且用户体验优秀的应用至关重要。

       DisplayManagerService源码解析,探究显示设备管理策略。了解DisplayManagerService的工作原理,有助于优化应用的显示性能和用户体验。

       如果你对以上内容感兴趣,点击下方卡片即可免费领取《Android Framework源码开发揭秘》学习手册,开始你的Android框架深入学习之旅!

更多内容请点击【百科】专栏