Android源代码结构分析
浅谈Android(安卓)
浅谈Android--嵌入式操作系统Android(读音:[ˈændrɔid],中文俗称安卓)是一个以Linux为基础的半开源操作系统,主要用于移动设备,由Google成立的Open Handset Alliance (OHA,开放手持设备联盟)持续领导与开发中。
--题记.维基百科说起嵌入式系统,曾经在保罗大叔的著作《黑客与画家》里看到多次,然后不明所以,就去查了嵌入式系统。
如果说嵌入式系统给我的第一印象是硬件,那么是我还不知道嵌入式在我生活里已经出现了很多年了。
大到冰箱,自动存款机(ATM),小到电子手表,遥控器。
在维基百科解答后,我对嵌入式直观的理解,是一种特定的植入硬件并极具针对性的计算机系统。
后来慢慢了解嵌入式的软件方面,就知道了嵌入式操作系统,而其中的佼佼者,就是如今已经超越ios,占据半壁江山的Android。
之所以会说Android,原因有二:一,因为Android如今炙手可热,在新一季度的日本手机软件营销额上,以Java等语言为Android系统开发的Apps,疯狂揽金,李开复断言在两年内,中国内地手机游戏软件市场,将会百花齐放;二,我虽并非研究Java也非致力于Android系统,但是Android系统的内核,却是我所熟悉的Linux内核。
而我将自己的开发平台转移到Linux系统,并以Python,Perl以及Lisp语言作为未来的生存工具,所以,就让我们谈一谈Android。
题记中套用维基百科对于Android的介绍,主要的目的,就是为了澄清一件事实“认知”——Android并没有真正的中文名。
Google并没有为Android命名,只有为其版本取名,且翻译成中文:4.2.x Jelly Bean 果冻豆,4.0.x Ice Cream Sandwich 冰激凌三明治,3.x.x HoneyComb 蜂巢,2.3.x Ginger Bread 姜饼。
而“安卓”一词,也是我们自己对其中文简称,就像Facebook并没有为其在中国大陆市场取名一样。
Android日志系统Logcat源代码简要分析
在前面两篇文章Android日志系统驱动程序Logger源代码分析和Android应用程序框架层和系统运行库层日志系统源代码中,介绍了Android内核空间层、系统运行库层和应用程序框架层日志系统相关的源代码,其中,后一篇文章着重介绍了日志的写入操作。
为了描述完整性,这篇文章着重介绍日志的读取操作,这就是我们在开发Android应用程序时,经常要用到日志查看工具Logcat了。
Logcat工具内置在Android系统中,可以在主机上通过adb logcat命令来查看模拟机上日志信息。
Logcat工具的用法很丰富,因此,源代码也比较多,本文并不打算完整地介绍整个Logcat工具的源代码,主要是介绍Logcat读取日志的主线,即从打开日志设备文件到读取日志设备文件的日志记录到输出日志记录的主要过程,希望能起到一个抛砖引玉的作用。
Logcat工具源代码位于system/core/logcat目录下,只有一个源代码文件logcat.cpp,编译后生成的可执行文件位于out/target/product/generic/system/bin目录下,在模拟机中,可以在/system/bin目录下看到logcat工具。
下面我们就分段来阅读logcat.cpp源代码文件。
一. Logcat工具的相关数据结构。
这些数据结构是用来保存从日志设备文件读出来的日志记录:view plain1.struct queued_entry_t {2.union {3. unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1] __attribute__((aligned(4)));4.struct logger_entry entry __attribute__((aligned(4)));5. };6. queued_entry_t* next;7.8. queued_entry_t() {9. next = NULL;10. }11.};12.13.struct log_device_t {14.char* device;15.bool binary;16.int fd;17.bool printed;18.char label;19.20. queued_entry_t* queue;21. log_device_t* next;22.23. log_device_t(char* d, bool b, char l) {24. device = d;25. binary = b;26. label = l;27. queue = NULL;28. next = NULL;29. printed = false;30. }31.32.void enqueue(queued_entry_t* entry) {33.if (this->queue == NULL) {34.this->queue = entry;35. } else {36. queued_entry_t** e = &this->queue;37.while (*e && cmp(entry, *e) >= 0) {38. e = &((*e)->next);39. }40. entry->next = *e;41. *e = entry;42. }43. }44.};其中,宏LOGGER_ENTRY_MAX_LEN和struct logger_entry定义在system/core/include/cutils/logger.h文件中,在Android应用程序框架层和系统运行库层日志系统源代码分析一文有提到,为了方便描述,这里列出这个宏和结构体的定义:view plain1.struct logger_entry {2. __u16 len; /* length of the payload */3. __u16 __pad; /* no matter what, we get 2 bytes of padding */4. __s32 pid; /* generating process's pid */5. __s32 tid; /* generating process's tid */6. __s32 sec; /* seconds since Epoch */7. __s32 nsec; /* nanoseconds */8.char msg[0]; /* the entry's payload */9.};10.11.#define LOGGER_ENTRY_MAX_LEN (4*1024)从结构体struct queued_entry_t和struct log_device_t的定义可以看出,每一个log_device_t都包含有一个queued_entry_t队列,queued_entry_t就是对应从日志设备文件读取出来的一条日志记录了,而log_device_t则是对应一个日志设备文件上下文。
Android应用程序绑定服务(bindService)的过程源代码分析
Android应用程序组件Service与Activity一样,既可以在新的进程中启动,也可以在应用程序进程内部启动;前面我们已经分析了在新的进程中启动Service的过程,本文将要介绍在应用程序内部绑定Service的过程,这是一种在应用程序进程内部启动Service的方法。
在前面一篇文章Android进程间通信(IPC)机制Binder简要介绍和学习计划中,我们就曾经提到,在Android系统中,每一个应用程序都是由一些Activity和Service组成的,一般Service运行在独立的进程中,而Activity有可能运行在同一个进程中,也有可能运行在不同的进程中;在接下来的文章中,Android系统在新进程中启动自定义服务过程(startService)的原理分析一文介绍了在新的进程中启动Service的过程,Android应用程序启动过程源代码分析一文介绍了在新的进程中启动Activity的过程,而Android应用程序内部启动Activity 过程(startActivity)的源代码分析一文则介绍了在应用程序进程内部启动Activity的过程;本文接过最后一棒,继续介绍在应用程序进程内部启动Service的过程,这种过程又可以称在应用程序进程内部绑定服务(bindService)的过程,这样,读者应该就可以对Android应用程序启动Activity和Service有一个充分的认识了。
这里仍然是按照老规矩,通过具体的例子来分析Android应用程序绑定Service的过程,而所使用的例子便是前面我们在介绍Android 系统广播机制的一篇文章Android系统中的广播(Broadcast)机制简要介绍和学习计划中所开发的应用程序Broadcast了。
我们先简单回顾一下这个应用程序实例绑定Service的过程。
在这个应用程序的MainActivity的onCreate函数中,会调用bindService 来绑定一个计数器服务CounterService,这里绑定的意思其实就是在MainActivity内部获得CounterService的接口,所以,这个过程的第一步就是要把CounterService启动起来。
Android系统架构及内核简介
Android系统架构及内核简介(来源于ThinkPHP)Android是Google公司开发的基于Linux平台的开源⼿机操作系统,它包括操作系统、中间件、⽤户界⾯和应⽤程序,⽽且不存在任何以往阻碍移动产业创新的专利权障碍,并由Google公司于2007年11⽉5⽇正式发布。
同时,Google公司组建了⼀个开放⼿机联盟,这个联盟由中国移动、摩托罗拉、⾼通、宏达电和T-Mobile等在内的全球30多家技术和⽆线应⽤的领军企业组成,Google通过与运营商、设备制造商、开发商和其他有关各⽅结成深层次的合作伙伴关系,希望借助建⽴标准化、开放式的移动电话软件平台,在移动产业内形成⼀个开放式的⽣态系统;可预见地,⽣产和使⽤基于 Android系统的嵌⼊式⼿持移动设备将是未来的发展趋势,对相应软件的需求量也将⽇趋增长,因此对Android系统内部作⼀个完整和深⼊的分析,对基于Android平台的软件移植和开发是很有益处的。
1 Android系统平台架构对操作系统⽽⾔,必须做到设计合理、层次分明,同时还需考虑整个系统的结构要聚耦适当,Android系统是基于linux内核的,因此还必须具备开源的特性,以符合开源⼈员共同⼯作。
从系统的组成要件来讲,Android平台架构包括硬件设备、板级⽀持包、驱动程序、操作系统内核、程序运⾏库,运⾏框架,应⽤程序等,它们的有机结合和协同⼯作共同完成了整个系统的正常运⾏和对事务的处理。
依据Google开源资料可知,整个系统由Linux内核、程序库、Android Runtime、应⽤程序框架和应⽤程序等5部分组成,,系统架构如图1所⽰。
参照图1,由上⽽下对组成系统各部分的主要组件作以下描述。
1.1 Linux内核Android基于Linux 2.6内核,但并⾮完全照搬内核,⽽是对内核作了部分增删和修改,在Linux 2.6内核的基础上,Android核⼼系统实现了安全性、内存管理、进程管理、⽹络协议栈和驱动模型等功能,Linux内核也同时作为硬件和软件栈之间的抽象层。
深入理解Android5源代码
深⼊理解Android5源代码深⼊理解Android 5 源代码1 Android系统介绍1.1 Android系统成功的秘诀1.1.1 获取了业界的⼴泛⽀持1.1.2 研发阵容强⼤1.1.3 为开发⼈员“精⼼定制”1.1.4 开源1.2 剖析Android系统架构1.2.1 底层操作系统层(OS)1.2.2 各种库(Libraries)和Android运⾏环境(RunTime)1.2.3 ApplicationFramework(应⽤程序框架)1.2.4 顶层应⽤程序(Application)1.3 五⼤组件1.3.1 Activity界⾯1.3.2 Intent和IntentFilters切换1.3.3 Service(服务)1.3.4 BroadcastReceiver发送⼴播1.3.5 ⽤ContentProvider存储数据1.4 进程和线程1.4.1 什么是进程1.4.2 什么是线程2 获取并编译Android源代码2.1 获取Android源代码2.1.1 在Linux系统中获取Android源代码2.1.2 在Windows平台获取Android源代码2.2 分析Android源代码结构2.2.1 总体结构2.2.2 应⽤程序部分2.2.3 应⽤程序框架部分2.2.4 系统服务部分2.2.5 系统程序库部分2.2.6 硬件抽象层部分2.3 Android源代码提供的接⼝2.3.1 暴露接⼝和隐藏接⼝2.3.2 调⽤隐藏接⼝2.4 编译源代码2.4.1 搭建编译环境2.4.2 在模拟器中运⾏2.5 编译源代码⽣成SDK3 分析Java Native Interface系统3.1 JNI基础3.1.1 JNI的功能结构3.1.2 JNI的调⽤层次3.1.3 分析JNI的本质3.2 分析MediaScanner3.2.1 分析Java层3.2.2 分析JNI层3.2.3 分析Native(本地)层3.3 分析Camera系统的JNI3.3.1 Java层预览接⼝3.3.2 注册预览的JNI函数3.3.3 C/C++层的预览函数4 分析HAL系统4.1 HAL基础4.1.1 推出HAL的背景4.1.2 HAL的基本结构4.2 分析HAL module架构4.2.1 hw_module_t4.2.2 结构hw_module_methods_t的定义4.2.3 hw_device_t结构4.3 分析⽂件hardware.c4.3.1 寻找动态链接库的地址4.3.2 数组variant_keys4.3.3 载⼊相应的库4.3.4 获得hw_module_t结构体4.4 分析硬件抽象层的加载过程4.5 分析硬件访问服务4.5.1 定义硬件访问服务接⼝4.5.2 具体实现4.6 分析Android官⽅实例4.6.1 获取实例⼯程源代码4.6.2 直接调⽤Service⽅法的实现代码4.6.3 通过Manager调⽤Service的实现代码4.7 HAL和系统移植4.7.1 移植各个Android部件的⽅式4.7.2 设置设备权限4.7.3 init.rc初始化4.7.4 ⽂件系统的属性5 分析IPC通信机制5.1 Binder机制概述5.2 分析Binder驱动程序5.2.1 分析数据结构5.2.2 分析设备初始化5.2.3 打开Binder设备⽂件5.2.4 内存映射5.2.5 释放物理页⾯5.2.6 分配内核缓冲区5.2.7 释放内核缓冲区5.2.8 查询内核缓冲区5.3 Binder封装库5.3.1 类BBinder5.3.2 类BpRefBase5.3.3 类IPCThreadState5.4 初始化Java层Binder框架5.5 分析MediaServer的通信机制5.5.1 MediaServer的⼊⼝函数5.5.2 ProcessState5.5.3 defaultServiceManager5.5.4 注册MediaPlayerService5.5.5 分析StartThread Pool和join Thread Pool6 分析Binder对象和Java接⼝6.1 分析实体对象(binder_node)6.2 分析本地对象(BBinder)6.3 分析引⽤对象(binder_ref)6.4 分析代理对象(BpBinder)6.5 分析Java接⼝6.5.1 获取Service Manager6.5.2 分析ActivityManagerService的Java层7 分析ServiceManager和MessageQueue 7.1 分析ServiceManager7.1.1 分析主⼊⼝函数7.1.2 打开Binder设备⽂件7.1.3 注册处理7.1.4 创建Binder实体对象7.1.5 尽职的循环7.1.6 将信息注册到ServiceManager7.1.7 分析MediaPlayerService和Client7.2 获得Service Manager接⼝7.3 分析MessageQueue7.3.1 创建MessageQueue7.3.2 提取消息7.3.3 分析函数nativePollOnce8 init进程和Zygote进程8.1 分析init进程8.1.1 分析⼊⼝函数8.1.2 分析配置⽂件8.1.3 分析Service8.1.4 解析on字段的内容8.1.5 init控制Service8.1.6 控制属性服务8.2 分析Zygote(孕育)进程8.2.1 Zygote基础8.2.2 分析Zygote的启动过程9 System进程和应⽤程序进程9.1 分析System进程9.1.1 启动System进程前的准备⼯作9.1.2 分析SystemServer9.1.3 分析EntropyService9.1.4 分析DropBoxManagerService9.1.5 分析DiskStatsService9.1.6 分析DeviceStorageManagerService(监测系统内存存储空间的状态)9.1.7 分析SamplingProfilerService9.2 分析应⽤程序进程9.2.1 创建应⽤程序9.2.2 启动线程池9.2.3 创建信息循环10 分析Activity组件10.1 Activity基础10.1.1 Activity状态10.1.2 剖析Activity中的主要函数10.2 分析Activity的启动源代码10.2.1 Launcher启动应⽤程序10.2.2 返回ActivityManagerService的远程接⼝10.2.3 解析intent的内容10.2.4 分析检查机制10.2.5 执⾏Activity组件的操作10.2.6 将Launcher推⼊Paused状态10.2.7 处理消息10.2.8 暂停完毕10.2.9 建⽴双向连接10.2.10 启动新的Activity10.2.11 通知机制10.2.12 发送消息11 应⽤程序管理服务——PackageManagerService分析11.1 PackageManagerService概述11.2 系统进程启动11.3 开始运⾏11.4 扫描APK⽂件11.5 解析并安装⽂件11.6 启动系统默认Home应⽤程序Launcher11.6.1 设置系统进程11.6.2 启动Home应⽤程序11.6.3 启动uncher11.6.4 加载应⽤程序11.6.5 获得Activity12 Content Provider存储机制12.1 Content Provider基础12.1.1 ContentProvider在应⽤程序中的架构12.1.2 ContentProvider的常⽤接⼝12.2 启动Content Provider12.2.1 获得对象接⼝12.2.2 存在校验12.2.3 启动Android应⽤程序12.2.4 根据进程启动Content Provider 12.2.5 处理消息12.2.6 具体启动12.3 Content Provider数据共享12.3.1 获取接⼝12.3.2 创建CursorWindow对象12.3.3 数据传递12.3.4 处理进程通信的请求12.3.5 数据操作13 分析⼴播机制源代码13.1 Broadcast基础13.2 发送⼴播信息13.2.1 intent描述指⽰13.2.2 传递⼴播信息13.2.3 封装传递13.2.4 处理发送请求13.2.5 查找⼴播接收者13.2.6 处理⼴播信息13.2.7 检查权限13.2.8 处理的进程通信请求13.3 分析BroadCastReceiver13.3.1 MainActivity的调⽤13.3.2 注册⼴播接收者13.3.3 获取接⼝对象13.3.4 处理进程间的通信请求14 分析电源管理系统14.1 Power Management架构基础14.2 分析Framework层14.2.1 ⽂件PowerManager.java14.2.2 提供PowerManager功能14.3 JNI层架构分析14.3.1 定义了两层之间的接⼝函数14.3.2 与Linux Kernel层进⾏交互14.4 Kernel(内核)层架构分析14.4.1 ⽂件power.c14.4.2 ⽂件earlysuspend.c14.4.3 ⽂件wakelock.c14.4.4 ⽂件resume.c14.4.5 ⽂件suspend.c14.4.6 ⽂件main.c14.4.7 proc⽂件14.5 wakelock和early_suspend14.5.1 wakelock的原理14.5.2 early_suspend的原理14.5.3 Android休眠14.5.4 Android唤醒14.6 Battery电池系统架构和管理14.6.1 实现驱动程序14.6.2 实现JNI本地代码14.6.3 Java层代码14.6.4 实现Uevent部分14.7 JobScheduler节能调度机制14.7.1 JobScheduler机制的推出背景14.7.2 JobScheduler的实现14.7.3 实现操作调度14.7.4 封装调度任务15 分析WindowManagerService系统15.1 WindowManagerService基础15.2 计算Activity窗⼝的⼤⼩15.2.1 实现View遍历15.2.2 函数relayoutWindow15.2.3 函数relayoutWindow15.2.4 拦截消息的处理类15.2.5 判断是否计算过16 分析电话系统16.1 Android电话系统详解16.1.1 电话系统简介16.1.2 电话系统结构16.1.3 驱动程序介绍16.1.4 RIL接⼝16.1.5 分析电话系统的实现流程16.2 电话系统中的⾳频模块16.2.1 ⾳频系统结构16.2.2 分析⾳频系统的层次16.3 分析拨号流程16.3.1 拨号界⾯16.3.2 实现Phone应⽤16.3.3 Call通话控制16.3.4 静态⽅法调⽤16.3.5 通话管理16.3.6 dial拨号16.3.7 状态跟踪16.3.8 RIL消息“出/⼊”⼝16.3.9 显⽰通话主界⾯17 分析短信系统17.1 短信系统的主界⾯17.2 发送普通短信17.3 发送彩信17.4 接收短信17.4.1 Java应⽤层的接收流程17.4.2 Framework层的处理过程18 Sensor传感器系统详解18.1 Android传感器系统概述18.2 Java层详解18.3 Frameworks层详解18.3.1 监听传感器的变化18.3.2 注册监听18.4 JNI层详解18.4.1 实现Native(本地)函数18.4.2 处理客户端数据18.4.3 处理服务端数据18.4.4 封装HAL层的代码18.4.5 处理消息队列18.5 HAL层详解19 分析SEAndroid系统19.1 SEAndroid概述19.1.1 内核空间19.1.2 ⽤户空间19.2 ⽂件安全上下⽂19.2.1 设置打包在ROM⾥⾯的⽂件的安全上下⽂19.2.2 设置虚拟⽂件系统的安全上下⽂19.2.3 设置应⽤程序数据⽂件的安全上下⽂19.3 进程安全上下⽂19.3.1 为独⽴进程静态地设置安全上下⽂19.3.2 为应⽤程序进程设置安全上下⽂20 分析ART系统20.1 对⽐Dalvik VM和ART20.2 启动ART20.2.1 运⾏app_process进程20.2.2 准备启动20.2.3 创建运⾏实例20.2.4 注册本地JNI函数20.2.5 启动守护进程20.2.6 解析参数20.2.7 初始化类、⽅法和域20.3 分析主函数main20.4 查找⽬标类20.4.1 函数LookupClass()20.4.2 函数DefineClass()20.4.3 函数InsertClass()20.4.4 函数LinkClass()20.5 类操作20.6 实现托管操作20.7 加载OAT⽂件20.7.1 产⽣OAT20.7.2 创建ART虚拟机20.7.3 解析启动参数并创建堆20.7.4 ⽣成指定⽬录⽂件20.7.5 加载OAT⽂件20.7.6 解析字段思维导图防⽌博客图床图⽚失效,防⽌图⽚源站外链:思维导图在线编辑链接:。
Android本质上就是一个基于Linux内核的操作系统
Android本质上就是一个基于Linux内核的操作系统。
与Ubuntu Linux、Fedora Linux 类似。
只是Android在应用层专门为移动设备添加了一些特有的支持。
既然Android是Linux内核的系统,那么基本的启动过程也应符合Linux的规则。
如果研究过其他Linux 系统应该了解,一个完整的Linux系统首先会将一个Linux内核装载到内存,也就是编译Linux内核源代码生成的bzImage文件,对于为Android优化的Linux内核源代码会生成zImage文件。
该文件就是Linux内核的二进制版本。
由于zImage在内核空间运行,而我们平常使用的软件都是在应用空间运行(关于内核空间和应用空间的详细描述,可以参考《Android深度探索(卷1):HAL与驱动开发》一书的内容,在后续的各卷中将会对Android的整体体系进行全方位的剖析)。
内核空间和应用空间是不能直接通过内存地址级别访问的,所以就需要建立某种通讯机制。
目前Linux有很多通讯机制可以在用户空间和内核空间之间交互,例如设备驱动文件(位于/dev目录中)、内存文件(/proc、/sys目录等)。
了解Linux的同学都应该知道Linux的重要特征之一就是一切都是以文件的形式存在的,例如,一个设备通常与一个或多个设备文件对应。
这些与内核空间交互的文件都在用户空间,所以在Linux内核装载完,需要首先建立这些文件所在的目录。
而完成这些工作的程序就是本文要介绍的init。
Init是一个命令行程序。
其主要工作之一就是建立这些与内核空间交互的文件所在的目录。
当Linux内核加载完后,要做的第一件事就是调用init程序,也就是说,init是用户空间执行的第一个程序。
在分析init的核心代码之前,还需要初步了解init除了建立一些目录外,还做了如下的工作1. 初始化属性2. 处理配置文件的命令(主要是init.rc文件),包括处理各种Action。
Android全面插件化RePlugin流程与源码解析
Android全面插件化RePlugin流程与源码解析Android全面插件化RePlugin流程与源码解析作者恋猫月亮2017.07.24 07:11字数4003阅读405评论6喜欢13赞赏1RePlugin,360开源的全面插件化框架,按照官网说的,其目的是“尽可能多的让模块变成插件”,并在很稳定的前提下,尽可能像开发普通App那样灵活。
那么下面就让我们一起深入♂了解它吧。
(ps :阅读本文请多参考源码图片( ̄^ ̄)ゞ)一、介绍RePlugin对比其他插件化,它的强大和特色,在于它只Hook住了ClassLoader。
One Hook这个坚持,最大程度保证了稳定性、兼容性和可维护性,详见《全面插件化——RePlugin的使命》。
当然,One Hook也极大的提高了实现复杂程度性,其中主要体现在:增加了Gradle插件脚本,实现开发中自动代码修改与生成。
分割了插件库和宿主库的代码实现。
代码中存在很多不少@deprecated、TODO和临时修改。
初始化、加载、启动等逻辑比较复杂。
图一Replugin项目结构本篇将竭尽所能,为各位介绍其流程和内部实现,如果存在一些地方存在纰漏,还请指出。
文章篇幅较长,需耐心阅读,阅读时可结合图片源码,同时欢迎收藏,或选择感兴趣点阅读,下面主要涉及:二、ClassLoader基础知识。
三、Replugin项目原理和结构分析。
四、Replugin的ClassLoader。
五、Replugin的相关类介绍。
六、Replugin的初始化。
七、Replugin启动Activity。
此处应有图二、ClassLoader基础知识既然Replugin选择Hook住ClassLoader,那先简单介绍下ClassLoader的基本知识吧,如熟悉者请略过。
ClassLoader又叫类加载器,是专门处理类加载,一个APP可以存在多个ClassLoader,它使用的是双亲代理模型,如下图所示,创建一个ClassLoader,需要使用一个已有的ClassLoader对象,作为新建的实例的ParentLoader。
Android开发之Android应用程序目录结构解析
Android开发之Android应⽤程序⽬录结构解析建⽴的HelloWorld的应⽤项⽬,其代码是由ADT插件⾃动⽣成的,形成Android项⽬特有的结构框架。
接下来让我带领⼤家解析⼀个Android程序的各个组成部分,这次我们拿⼀个Hello,World做例⼦,虽然只是⼀个Hello,World,但也是⿇雀虽⼩五脏俱全,通过分析Hello,World的⽬录结构,让我们对Android程序有⼀个整体全⾯的认识。
⼀、创建⼀个Android 应⽤项⽬启动Eclipse;选择File->New->Project…;选择Android 下的Android Project,单击Next按钮。
根据上⾯的⽬录结构,我们来分析⼀下⼆、⽬录解析我们来⼤致了解⼀下安卓应⽤程序的⽬录的作⽤:1. src⽬录该⽬录下的⽂件存放Android应⽤程序中所有java源代码,⾃动地组织在⽤户定义声明的包内。
Activity是Android中的视图部分,负责界⾯显⽰。
2. gen⽬录该⽬录下的⽂件是由ADT⾃动⽣成的,即包内的R.java⽂件。
该⽂件为项⽬中的各个资源在该类中创建其唯⼀的ID。
从R⽂件中可以看到每⼀个资源都会有⼀个整数和它相对应。
3. Android4.4建⽴不同版本的可能会有不同的依赖。
Android4.4 ⽬录存放该项⽬⽀持的jar包。
作为⼀个Java项⽬,通常情况下都会引⼊要⽤到的⼯具类,也就是Jar包,在Android开发中,绝⼤部分开发⽤的⼯具包都被封装到⼀个名叫Android.jar的⽂件⾥了。
如果我们在Eclipse中展开来看,可以看到j2se中的包,apache项⽬中的包,还有Android⾃⾝的包⽂件。
在这⾥我们简单浏览⼀下Android的包⽂件:android.app :提供⾼层的程序模型、提供基本的运⾏环境android.content :包含各种的对设备上的数据进⾏访问和发布的类android.database :通过内容提供者浏览和操作数据库android.graphics :底层的图形库,包含画布,颜⾊过滤,点,矩形,可以将他们直接绘制到屏幕上.android.location :定位和相关服务的类android.media :提供⼀些类管理多种⾳频、视频的媒体接⼝ :提供帮助⽹络访问的类,超过通常的.* 接⼝android.os :提供了系统服务、消息传输、IPC 机制android.opengl :提供OpenGL 的⼯具android.provider :提供类访问Android 的内容提供者android.telephony :提供与拨打电话相关的API 交互android.view :提供基础的⽤户界⾯接⼝框架android.util :涉及⼯具性的⽅法,例如时间⽇期的操作android.webkit :默认浏览器操作接⼝android.widget :包含各种UI 元素(⼤部分是可见的)在应⽤程序的屏幕中使⽤4. assets存放项⽬相关的资源⽂件5. bin该⽬录⽤于存放⽣成的⽬标⽂件,例如Java的⼆进制⽂件、资源打包⽂件(.ap_后缀)、Dalvik虚拟机的可执⾏性⽂件(.dex后缀),打包好应⽤⽂件(.apk后缀)等。
android_source讲解
2、将Android源代码作为一个工程导入Eclipse
Android源码又大又多,查看起来非常不方便,为了更方便的查看源代码,可以将Android源 代码作为一个工程,导入到Eclipse中去 步骤: 1、将development/ide/eclipse/下的.classpath文件拷贝到源代码的根目录下 2、把android-formatting.xml、android.importorder导入eclipse android-formatting.xml、.classpath和android.importorder都放在development/ide/eclipse/下 android-formatting.xml用来配置eclipse编辑器的代码风格;android.importorder用来配置 eclipse的import的顺序和结构。 3、新建java工程 工程名任意,选择Create project from existing source 选中源代码目录 注意:在导入的时候可能会出现路径duplicate path 的错误。这时候要修改源代码根目录下 的.classpath文件 如果出现两个相同的条目,则需要删除一条 <classpathentry kind="src" path="frameworks/base/vpn/java"/> <classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/vpn/java"/>
Android源代码
1、Android源代码结构的简要介绍 2、将Android源代码作为一个工程导入Eclipse 3、让Eclipse关联到Android api源代码
安卓原生系统中邮件的代码
安卓原生系统中邮件的代码An droid包含了原始An droid的目标机代码,主机编译工具、仿真环境,下载的代码包经过解压后(这里是Android2.2的源码包),源代码的第一层目录结构如下:|-- Makefile|-- bionic|-- bootable |-- build (bionic C 库)(启动引导相关代码)(存放系统编译规则及gen eric等基础开发包配置)|-- cts卜-dalvik|-- developme nt|-- exter nal|-- frameworks |-- hardware |-- libcore|-- ndk|-- device|-- out|-- packages |-- prebuilt|-- sdk|-- system(An droid兼容性测试套件标准)(dalvik JAVA 虚拟机)(应用程序开发相关)(an droid使用的一些开源的模组)(核心框架 --- java及C++语言)(主要保护硬解适配层HAL代码)(编译完成后的代码输出与此目录)(应用程序包)(x86和arm架构下预编译的一些资源)(sdk及模拟器)(文件系统库、应用及组件一一C语言)C 库) libdl 实现, dl 是动态链接,提供访问动态链接库的功能) |-- arch-arm( ARM 架构,包含系统调用汇编实现) |-- arch-x86( x86 架构,包含系统调用汇编实现) |-- bionic(由 C 实现的功能,架构无关) |-- docs(文档) |-- include(头文件) |-- inet|-- kernel( Linux 内核中的一些头文件) |-- netbsd(? netbsd 系统相关,具体作用不明) |-- private(?一些私有的头文件) |-- stdio( stdio 实现) |-- stdlib( stdlib 实现) |-- string( string 函数实现) |-- tools(几个工具) |-- tzcode(时区相关代码) |-- unistd( unistd 实现) '--zoneinfo(时区信息) | | | | | || | | | | | | | | |bionic 目录|-- libc|-- libdl| |-- alpha (apaha 架构)| |-- amd64 (amd64 架构)| |-- arm (arm 架构)| |-- bsdsrc (?bsd 的源码)| |-- i386 (i386 架构)| |-- i387 (i387 架构?)| |-- ia64 (ia64 架构)| |-- include (头文件)| |-- man (数学函数,后缀名为.3 ,一些为freeBSD 的库文件)| |-- powerpc (powerpc 架构)| |-- sparc64 (sparc64 架构)| 、-- src (源代码)|-- libstdc++ (libstdc++ C++ 实现库)| |-- include (头文件)| 、-- src (源码)|-- libthread_db (多线程程序的调试器库)| '--in elude (头文件)'--li nker (动态链接器)'-- arch (支持arm 和x86 两种架构)bootable 目录bootloader (适合各种bootloader 的通用代码)'--legacy (估计不能直接使用,可以参考)|-- arch_armv6 (V6 架构,几个简单的汇编文件)|-- arch_msm7k (高通7k 处理器架构的几个基本驱动)|-- include (通用头文件和高通7k 架构头文件)|-- libboot (启动库,都写得很简单)|-- libc (一些常用的c 函数)|-- nandwrite (nandwirte 函数实现)'-- usbloader (usbloader 实现)diskinstaller (android 镜像打包器,x86 可生产iso recovery (系统恢复相关)|-- edify (升级脚本使用的edify 脚本语言)|-- etc (init.rc 恢复脚本)|-- minui (一个简单的UI )|-- minzip (一个简单的压缩工具)|-- mtdutils (mtd 工具)|-- res (资源)| '-- images (一些图片)|-- tools (工具)| '-- ota (OTA Over The Air Updates 升级工具)'-- updater (升级器)build 目录|-- core (核心编译规则)|-- history (历史记录)libs| '-- host (主机端库,有android “cp ”功能替换)|-- target (目标机编译对象)| |-- board (开发平台)| | |-- emulator (模拟器)| | |-- generic (通用)| | |-- idea6410 (自己添加的)| | 、-- sim (最简单)| 、-- product (开发平台对应的编译规则)| '-- security (密钥相关)'--tools (编译中主机使用的工具及脚本)|-- acp ( Android "acp" Command )|-- apicheck (api 检查工具)|-- applypatch (补丁工具)|-- apriori (预链接工具)|-- atree (tree 工具)|-- bin2asm (bin 转换为asm 工具)|-- dexpreopt (模拟器相关工具,具体功能不明)|-- droiddoc (?作用不明,java 语言,网上有人说和JDK5 有关)|-- fs_config ( This program takes a list of files and directories ) |-- fs_get_stats (获取文件系统状态)|-- iself (判断是否ELF 格式)|-- isprelinked (判断是否prelinked )|-- kcm (按键相关)|-- lsd (List symbol dependencies )|-- releasetools (生成镜像的工具及脚本)|-- rgb2565 (rgb 转换为565 )|-- signapk (apk 签名工具)|-- soslim (strip 工具)zipalig n ( zip archive alignment tool )。
Android全面插件化RePlugin流程与源码解析
Android全面插件化RePlugin流程与源码解析Android全面插件化RePlugin流程与源码解析作者恋猫月亮2017.07.24 07:11字数4003阅读405评论6喜欢13赞赏1RePlugin,360开源的全面插件化框架,按照官网说的,其目的是“尽可能多的让模块变成插件”,并在很稳定的前提下,尽可能像开发普通App那样灵活。
那么下面就让我们一起深入♂了解它吧。
(ps :阅读本文请多参考源码图片( ̄^ ̄)ゞ)一、介绍RePlugin对比其他插件化,它的强大和特色,在于它只Hook住了ClassLoader。
One Hook这个坚持,最大程度保证了稳定性、兼容性和可维护性,详见《全面插件化——RePlugin的使命》。
当然,One Hook也极大的提高了实现复杂程度性,其中主要体现在:增加了Gradle插件脚本,实现开发中自动代码修改与生成。
分割了插件库和宿主库的代码实现。
代码中存在很多不少@deprecated、TODO和临时修改。
初始化、加载、启动等逻辑比较复杂。
图一Replugin项目结构本篇将竭尽所能,为各位介绍其流程和内部实现,如果存在一些地方存在纰漏,还请指出。
文章篇幅较长,需耐心阅读,阅读时可结合图片源码,同时欢迎收藏,或选择感兴趣点阅读,下面主要涉及:二、ClassLoader基础知识。
三、Replugin项目原理和结构分析。
四、Replugin的ClassLoader。
五、Replugin的相关类介绍。
六、Replugin的初始化。
七、Replugin启动Activity。
此处应有图二、ClassLoader基础知识既然Replugin选择Hook住ClassLoader,那先简单介绍下ClassLoader的基本知识吧,如熟悉者请略过。
ClassLoader又叫类加载器,是专门处理类加载,一个APP可以存在多个ClassLoader,它使用的是双亲代理模型,如下图所示,创建一个ClassLoader,需要使用一个已有的ClassLoader对象,作为新建的实例的ParentLoader。
Android Telephony原理解析与开发指南
6.2.4 更新 mState
6 Voice Call语音通话模型
6.3.1 GsmCdmaCall
01
6.3.3 DriverCall、 Call、Connection
03
02
6.3.2 GsmCdmaConnecti
on
6.3 通话管理模型分析
6 Voice Call语 音通话模型
6.4 补充通话连接断开处理 机制
息
03 7.4.3 展示小区信
息
02 7 .4. 2 扩展 ITelephonyRegistry
04 7.4.4 小区信息更
新源头
05 7.4.5 信号强度实
时变化
7.5.1 飞行模式开启关 闭入口逻辑
7.5.3 WiFi模块开启关 闭
7.5.2 Radio模块开启关 闭
7.5.4 蓝牙模块开启关 闭
4.1.4 第二个拨号入口
4 详解Telecom
4.2.1 汇总 frameworks/base/telecomm代码
4.2.4 演进Telecom交互 模型
02 01
03 04
4.2.2 绑定 IInCallService机制
4.2 Telecom交互模型
4.2.3 绑定 IConnectionService机制
6.1 详解 GsmCdmaCallTracker
6.4 补充通话连 接断开处理机制
6.2 handlePollCalls 方法
6.5 区分 Connection
6.3 通话管理 模型分析
6.6 扩展 InCallUi
6 Voice Call语音通话模型
6.7 验证Call运行模型
本章小结
2.Android源代码编译命令m和mm和mmm以及make分析
老罗的新浪微博:/shengyangluo,欢迎关注!在前文中,我们分析了Android编译环境的初始化过程。
Android编译环境初始化完成后,我们就可以用m/mm/mmm/make命令编译源代码了。
当然,这要求每一个模块都有一个Android.mk文件。
Android.mk实际上是一个Makefile脚本,用来描述模块编译信息。
Android编译系统通过整合Android.mk文件完成编译过程。
本文就对Android源代码的编译过程进行详细分析。
从前面Android编译系统环境初始化过程分析这篇文章可以知道,lunch命令其实是定义在build/envsetup.sh文件中的函数lunch提供的。
与lunch命令一样,m、mm和mmm 命令也分别是由定义在build/envsetup.sh文件中的函数m、mm和mmm提供的,而这三个函数又都是通过make命令来对源代码进行编译的。
事实上,命令m就是对make命令的简单封装,并且是用来对整个Android源代码进行编译,而命令mm和mmm都是通过make命令来对Android源码中的指定模块进行编译。
接下来我们就先分别介绍一下函数m、mm和mmm的实现,然后进一步分析它们是如何通过make命令来编译代码的。
函数m的实现如下所示:函数m调用函数gettop得到的是Android源代码根目录T。
在执行make命令的时候,先通过-C选项指定工作目录为T,即Android源代码根目录,接着又将执行命令m指定的参数$@作为命令make的参数。
从这里就可以看出,命令m实际上就是对命令make的简单封装。
函数mm的实现如下所示:函数mm首先是判断当前目录是否就是Android源码根目录,即当前目录下是否存在一个build/core/envsetup.mk文件和一个Makefile文件。
如果是的话,就将命令mm当作是一个普通的make命令来执行。
否则的话,就调用函数findmakefile从当前目录开始一直往上寻找是否存在一个Android.mk文件。
Android源码分析:AudioPolicy
Android源码分析:AudioPolicyAndroid源码分析:AudioPolicy在创建一个AudioPolicyService对象时,主要是:1. 创建两个AudioCommand线程,一个线程用于T one的播放,另一个用于声音的音量及其它参数设置;2.创建音频策略管理器(AudioPolicyManager)。
Android Frameworks为音频策略管理器定义了统一的接口--AudioPolicyInterface,并提供一个缺省的音频管理器--AudioPolicyManagerBase,它为运行在模拟器上Android所使用,也可以使用宏激活该通用管理器。
不同的硬件厂商,可以编写一个继承AudioPolicyInterface的子类,针对自己的硬件平台,实现自己的音频策略管理。
在音频策略服务(AudioPolicyService)中,会根据一定的条件去判断创建何种音频策略管理器:AudioPolicyService::AudioPolicyService(): BnAudioPolicyService() , mpPolicyManager(NULL){char value[PROPERTY_VALUE_MAX];// start tone playback threadmTonePlaybackThread = new AudioCommandThread(String8(“”));// start audio commands threadmAudioCommandThread = new AudioCommandThread(String8(“ApmCommandThread”));#if (defined GENERIC_AUDIO) || (defined AUDIO_POLICY_TEST)mpPolicyManager = new AudioPolicyManagerBase(this);//通用类型LOGV(“build for GENERIC_AUDIO –using generic audiopolicy”);#else// if running in emulation – use the emulator driverif (property_get(“ro.kernel.qemu”, value, 0)) {LOGV(“Running in emulation –using generic audio policy”);mpPolicyManager = new AudioPolicyManagerBase(this);//Android模拟器上,注意将this 指针传递了过去,实际上AudioPolicyService也继承了AudioPolicyClientInterface的缘故,因此可以把它看作该接口的指针。
Android系统Framework层源码分析
动态方法
亲,您们从前面静态方法的介绍中看到了什么? native函数和JNI层的函数,不就是找一函数指针嘛? “不找贵的,只找对的......”
关键数据结构:JNINativeMethod 如何注册?
Quick Question: 1 什么时候,在哪儿注册JNINativeMethod数组?
Answer: 在一个特殊的native函数中...... Quesiton: 这个特殊的native函数又是在什么时候,在哪儿注册的? Answer: 鸡生蛋?蛋生鸡?......
Global Reference:全局引用,这种对象如不主动释放, 就永远不会被垃圾回收。 Weak Global Reference:弱全局引用,一种特殊的 Global Reference。在运行过程中可能会被垃圾回收。
所以在程序中使用它之前,
需要调用JNIEnv的IsSameObject判断它是不是被回收了。
sp的构造
//mRefs就是刚才RefBase构造函数中new出来的影子对象
continue incStrong
调试版的:这几个函数将 do nothing!
//原子操作,影子对象的弱引用计数加1
//刚才增加了弱引用计数,再增加强引用计数
//下面函数为原子加1操作,并返回旧值。所以c=0x1000000,而mStrong变为0x1000001
2.1 keywords.h的用法
声明一些Action函数 定义KEYWORD宏,四个参数, 却只用到第一个参数
使用KEYWORD宏,得到一个枚举: enum{ K_UNKNOWN, K_class, K_on
……
}
两次include keywords.h
第一次包含:得到枚举定义和一些函数
Android系统的分析
Android系统的分析康磊Kang Lei河北科技师范学院欧美学院,河北省秦皇岛066004Hebei Normal University of Science & Technology E&A College, Qinhuangdao Hebei 066004, ChinaEmail:1522647802@摘要Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发。
在网络高速发展的时代,了解Android系统构架及组成对一个人今后的发展会有很大的帮助。
本文主要对系统层次,系统结构,应用组件等三个方面对Android系统进行了分析。
系统层次,Android的系统层次和其操作系统一样,分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和Linux内核层。
系统结构方面,本文从后缀简介、硬件抽像层、中介软件、安全权限机制等四方面进行介绍。
应用组件,Android开发四大组件分别是:活动(Activity):用于表现功能。
服务(Service):后台运行服务,不提供界面呈现。
广播接收器(BroadcastReceiver):用于接收广播。
内容提供商(Content Provider):支持在多个应用中存储和读取数据,相当于数据库。
关键词:Android系统;系统层次;系统结构;应用组件;系统分析AbstractAndroid is a free and open-source Linux-based operating system, mainly used in mobile devices, such as smart phonesand tablet PCs by Google and the Open Handset Alliance leadership and development. In the era of rapid development of the network, understand the Android system architecture and composition of the future development of a person will be of great help.This paper focuses on three aspects of the System level, system architecture, application components of the Android system were analyzed.System level, Android's system level and its operating system, divided into four levels, from high-level to low-level application layer, the application framework layer, the system runtime layer and the Linux kernel layer.System architecture, the paper introduced from the four aspects of the suffix, hardware abstraction layer, middleware, security permissions mechanism.Application components, Android development of four major components: activities: for performance.Services: running in the background and does not provide the interface presents.Broadcast receiver: means for receiving the broadcast.Content providers: support multiple applications to store and read data, the equivalent of a database.Keywords:Android system ; System level ; system architecture ; application components; system analysis0引言Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发。
android输入法01:SoftKeyboard源码解析01
android输入法01:SoftKeyboard源码解析01本文主要介绍android自带输入法实例SoftKeyboard的源码,共分为两篇:第一篇为SoftKeyboard框架概述,第二篇为源码注释。
1、IMF简介一个IMF结构中包含三个主要的部分:•i nput method manager:管理各部分的交互。
它是一个客户端API,存在于各个应用程序的context中,用来沟通管理所有进程间交互的全局系统服务。
•i nput method(IME):实现一个允许用户生成文本的独立交互模块。
系统绑定一个当前的输入法。
使其创建和生成,决定输入法何时隐藏或者显示它的UI。
同一时间只能有一个IME运行。
•c lient application:通过输入法管理器控制输入焦点和IME的状态。
一次只能有一个客户端使用IME。
1.1 InputManager由UI控件(View,TextView,EditText等)调用,用来操作输入法。
比如,打开,关闭,切换输入法等。
它是整个输入法框架(IMF)结构的核心API,处理应用程序和当前输入法的交互。
可以通过Context.getSystemService()来获取一个InputMethodManager的实例。
在开发过程中,最基础最重要的就是养成阅读API的习惯。
优秀的程序员要养成把自己关在小黑屋里,断绝与外界的联网和联系,仅仅靠自己电脑中的开发环境和API文档,以及漂亮女仆送来的每天三顿饭,写出优秀的程序。
这个在武侠小说中叫闭关,在软件开发中叫Clean Room,哈哈。
Android的API文档在:%SDK_ROOM%/docs/reference/index.html,InputManager类的位置:%SDK_ROOM%/docs/reference/android/view/inputmethod/InputMethodManager.html 由于,该类跟本次要讲的Sample关系不大,这里就不详细分析,请各位自行阅读API doc吧。
Android8.1SystemUI源码分析之Notification流程
Android8.1SystemUI源码分析之Notification流程代码流程1、先看UI显⽰,StatuBar加载 CollapsedStatusBarFragment 替换 status_bar_container(状态栏通知显⽰区域)SystemUI\src\com\android\systemui\statusbar\phone\StatusBar.javaFragmentHostManager.get(mStatusBarWindow).addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {CollapsedStatusBarFragment statusBarFragment =(CollapsedStatusBarFragment) fragment;statusBarFragment.initNotificationIconArea(mNotificationIconAreaController);mStatusBarView = (PhoneStatusBarView) fragment.getView();mStatusBarView.setBar(this);mStatusBarView.setPanel(mNotificationPanel);mStatusBarView.setScrimController(mScrimController);mStatusBarView.setBouncerShowing(mBouncerShowing);setAreThereNotifications();checkBarModes();/// M: add for plmn display feature @{attachPlmnPlugin();///@}}).getFragmentManager().beginTransaction().replace(R.id.status_bar_container, new CollapsedStatusBarFragment(),CollapsedStatusBarFragment.TAG).commit();statusBarFragment.initNotificationIconArea(mNotificationIconAreaController) 初始化通知栏区域,这是我们关⼼的mStatusBarView.setBar(this) 传递statusBar处理下拉事件mStatusBarView.setPanel(mNotificationPanel) 传递 NotificationPanelView 显⽰下拉UI控制2、跟进 CollapsedStatusBarFragment 中,先看布局⽂件 status_bar.xml1、notification_lights_out---ImageView默认gone2、status_bar_contents--LinearLayoutnotification_icon_area--FrameLayoutsystem_icon_area--LinearLayoutsystem_icons.xml(蓝⽛、wifi、VPN、⽹卡、SIM卡信号、飞⾏模式等) 电池clock--Clock.java3、emergency_cryptkeeper_text--ViewStub(延迟加载紧急电话⽂字)这就是我们看到的statusBar的布局,本篇只关⼼ notification_icon_area,其它的以后再进⾏分析。
Android12系统源码分析:NativeTombstoneManager
Android12系统源码分析:NativeTombstoneManagerAndroid12系统源码分析:NativeTombstoneManager概述android12新增的system_server进程(LocalService)本地服务,⽤于管理native tombstones。
该服务在开机Systemerver初始化流程启动,添加到LocalService,然后启动⼀个ServiceThread线程⽤于(mHandler.post)处理本服务的业务。
NativeTombstoneManager的功能主要是:监听/data/tombstones ⽬录⽂件变动,解析为TombstoneFile 对象保存,通知dropbox特定tombstones ⽂件删除特定tombstones ⽂件检索值得关注的是AMS对该服务的使⽤,也是Android11新增API:getHistoricalProcessExitReasons()软件架构如图:BootReceiver SystemServer 开机启动仅添加本地服务LocalServices.addService NativeTombstoneManager.class SystemService AppExitInfoTracker Nativ eTombs toneManager tombs toneServ ic e void clearHistoryProcessExitInfo()ActivityManagerService Nativ eTombs toneManager tombs toneServ ic e public getHistoricalProcessExitReasons()暴露接⼝给appNativeTombstoneManagerServiceNativ eTombs toneManager mManagerpublic v oid onStart()public v oid onBootPhas e()TombstoneFile by:qiuchengParcelFileDescriptorRetrieverNativeTombstoneManagerpriv ate v oid handleTombs tone()priv ate v oid handleProtoTombs tone()public v oid c ollec tTombs tones ()服务核⼼实现TombstoneWatcher 监听⽬录:/data/tombstones FileObserver 图:NativeTombstoneManager类图启动流程SystemServer SystemServer SystemServiceManager SystemServiceManager NativeTombstoneManagerService NativeTombstoneManagerService NativeTombstoneManager NativeTombstoneManager LocalServicesLocalServices 1startCoreServices23by:qiucheng4NativeTombstoneManager567addService(NativeTombstoneManager.class8startOtherServices9startBootPhasePHASE_ACTIVITY_MANAGER_READY10onBootPhase111213registerForPackageRemoval14handleTombstone图:NativeTombstoneManager服务启动时序图服务⽐较简单,和其他SystemServer启动的服务⼀样,frameworks/base/services/core/java/com/android/server/os/NativeTombstoneManagerService.java public class NativeTombstoneManagerService extends SystemService {private NativeTombstoneManager mManager;@Overridepublic void onStart() {mManager = new NativeTombstoneManager(getContext());//仅添加本地服务,没有binder服务LocalServices.addService(NativeTombstoneManager.class, mManager);}@Overridepublic void onBootPhase(int phase) {if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {mManager.onSystemReady();}}}本服务也是SystemService⼯具类的⼦类,通过重写onStart、onBootPhase获得代码流程在onStart中初始化真正的服务实现NativeTombstoneManager,实例化后添加到LocalServicesframeworks/base/services/core/java/com/android/server/os/NativeTombstoneManager.javapublic final class NativeTombstoneManager {NativeTombstoneManager(Context context) {//启动handler线程,⽤于后续处理本服务的业务final ServiceThread thread = new ServiceThread(TAG + ":tombstoneWatcher",THREAD_PRIORITY_BACKGROUND, true /* allowIo */);thread.start();mHandler = thread.getThreadHandler();//启动⽂件监听/data/tombstonesmWatcher = new TombstoneWatcher();mWatcher.startWatching();}void onSystemReady() {registerForUserRemoval();registerForPackageRemoval();// 开机阶段先扫描⼀次/data/tombstones⽬录mHandler.post(() -> {final File[] tombstoneFiles = TOMBSTONE_DIR.listFiles();for (int i = 0; tombstoneFiles != null && i < tombstoneFiles.length; i++) {if (tombstoneFiles[i].isFile()) {handleTombstone(tombstoneFiles[i]);开机流程有三个动作启动handler线程,⽤于后续处理本服务的业务TombstoneWatcher启动⽂件监听/data/tombstones开机阶段先扫描⼀次/data/tombstones⽬录看⼀下handleTombstoneframeworks/base/services/core/java/com/android/server/os/NativeTombstoneManager.javaprivate void handleTombstone(File path) {final String filename = path.getName();if (!filename.startsWith("tombstone_")) {return;}if (filename.endsWith(".pb")) {handleProtoTombstone(path);BootReceiver.addTombstoneToDropBox(mContext, path, true);} else {BootReceiver.addTombstoneToDropBox(mContext, path, false);如果是以pb结尾的原型⽂件,则handleProtoTombstone⽅法中为该⽂件⽣成TombstoneFile对象,并添加到数据结构private final SparseArray<TombstoneFile> mTombstones;并且,每个新⽣成的tombstone⽂件都会同步给dropbox新⽂件的监听frameworks/base/services/core/java/com/android/server/os/NativeTombstoneManager.javaclass TombstoneWatcher extends FileObserver {TombstoneWatcher() {super(TOMBSTONE_DIR, FileObserver.CREATE | FileObserver.MOVED_TO);}@Overridepublic void onEvent(int event, @Nullable String path) {mHandler.post(() -> {handleTombstone(new File(TOMBSTONE_DIR, path));});内部类TombstoneWatcher,当⽬录/data/tombstones有⽂件⽣成时,回调到onEvent,然后通过handleTombstone⽅法做处理AciivtyManager#getHistoricalProcessExitReasonsActivityManager ActivityManager ActivityManagerServiceActivityManagerServiceLocalServicesLocalServicesNativeTombstoneManagerNativeTombstoneManagergetHistoricalProcessExitReasonsenforceNotIsolatedCallerenforceDumpPermissionForPackageby:qiuchenggetServicecollectTombstonesnew ParceledListSlice<ApplicationExitInfo>(results)图:getHistoricalProcessExitReasons⽅法时序图需要注意返回的数据结构的处理ApplicationExitInfo。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
目录一、源代码结构 (2)第一层次目录 (2)bionic目录 (3)bootloader目录 (5)build目录 (7)dalvik目录 (9)development目录 (9)external目录 (13)frameworks目录 (19)Hardware (20)Out (22)Kernel (22)packages目录 (22)prebuilt目录 (27)SDK (28)system目录 (28)Vendor (32)一、源代码结构第一层次目录Google提供的Android包含了原始Android的目标机代码,主机编译工具、仿真环境,代码包经过解压缩后,第一级别的目录和文件如下所示:.|-- Makefile (全局的Makefile)|-- bionic (Bionic含义为仿生,这里面是一些基础的库的源代码)|-- bootloader (引导加载器),我们的是bootable,|-- build (build目录中的内容不是目标所用的代码,而是编译和配置所需要的脚本和工具)|-- dalvik (JAVA虚拟机)|-- development (程序开发所需要的模板和工具)|-- external (目标机器使用的一些库)|-- frameworks (应用程序的框架层)|-- hardware (与硬件相关的库)|-- kernel (Linux2.6的源代码)|-- packages (Android的各种应用程序)|-- prebuilt (Android在各种平台下编译的预置脚本)|-- recovery (与目标的恢复功能相关)`-- system (Android的底层的一些库)bionic目录bionic C库bionic目录展开一个级别的目录如下所示:bionic/|-- Android.mk|-- libc|-- libdl|-- libm|-- libstdc++|-- libthread_db`-- linkerbionic 目录|-- libc (C库)| |-- arch-arm (ARM架构,包含系统调用汇编实现)| |-- arch-x86 (x86架构,包含系统调用汇编实现)| |-- bionic (由C实现的功能,架构无关)| |-- docs (文档)| |-- include (头文件)| |-- inet (?inet相关,具体作用不明)| |-- kernel (Linux内核中的一些头文件)| |-- netbsd (?nesbsd系统相关,具体作用不明)| |-- private (?一些私有的头文件)| |-- stdio (stdio实现)| |-- stdlib (stdlib实现)| |-- string (string函数实现)| |-- tools (几个工具)| |-- tzcode (时区相关代码)| |-- unistd (unistd实现)| `-- zoneinfo (时区信息)|-- libdl (libdl实现,dl是动态链接,提供访问动态链接库的功能)|-- libm (libm数学库的实现,)| |-- alpha (apaha架构)| |-- amd64 (amd64架构)| |-- arm (arm架构)| |-- bsdsrc (?bsd的源码)| |-- i386 (i386架构)| |-- i387 (i387架构?)| |-- ia64 (ia64架构)| |-- include (头文件)| |-- man (数学函数,后缀名为.3,一些为freeBSD的库文件)| |-- powerpc (powerpc架构)| |-- sparc64 (sparc64架构)| `-- src (源代码)|-- libstdc++ (libstdc++ C++实现库)| |-- include (头文件)| `-- src (源码)|-- libthread_db (多线程程序的调试器库)| `-- include (头文件)`-- linker (动态链接器)`-- arch (支持arm和x86两种架构)bootloader目录启动引导相关代码bootloader目录展开的两个级别目录:bootloader/`-- legacy|-- Android.mk|-- README|-- arch_armv6|-- arch_msm7k|-- fastboot_protocol.txt|-- include|-- libboot|-- libc|-- nandwrite`-- usbloaderbootable 目录.|-- bootloader (适合各种bootloader的通用代码)| `-- legacy (估计不能直接使用,可以参考)| |-- arch_armv6 (V6架构,几个简单的汇编文件)| |-- arch_msm7k (高通7k处理器架构的几个基本驱动)| |-- include (通用头文件和高通7k架构头文件)| |-- libboot (启动库,都写得很简单)| |-- libc (一些常用的c函数)| |-- nandwrite (nandwirte函数实现)| `-- usbloader (usbloader实现)|-- diskinstaller (android镜像打包器,x86可生产iso)`-- recovery (系统恢复相关)|-- edify (升级脚本使用的edify脚本语言)|-- etc (init.rc恢复脚本)|-- minui (一个简单的UI)|-- minzip (一个简单的压缩工具)|-- mtdutils (mtd工具)|-- res (资源)| `-- images (一些图片)|-- tools (工具)| `-- ota (OTA Over The Air Updates升级工具)`-- updater (升级器)build目录存放系统编译规则及generic等基础开发包配置build目录展开的一个级别的目录如下所示:build/|-- buildspec.mk.default|-- cleanspec.mk|-- core (各种以mk为结尾的文件,它门是编译所需要的Makefile)|-- envsetup.sh|-- libs|-- target (包含board和product两个目录,为目标所需要文件)`-- tools (编译过程中主机所需要的工具,一些需要经过编译生成)其中,core中的Makefile是整个Android编译所需要的真正的Makefile,它被顶层目录的Makefile引用。
envsetup.sh是一个在使用仿真器运行的时候,用于设置环境的脚本。
build目录|-- core (核心编译规则)|-- history (历史记录)|-- libs| `-- host (主机端库,有android “cp”功能替换)|-- target (目标机编译对象)| |-- board (开发平台)| | |-- emulator (模拟器)| | |-- generic (通用)| | |-- idea6410 (自己添加的)| | `-- sim (最简单)| `-- product (开发平台对应的编译规则)| `-- security (密钥相关)`-- tools (编译中主机使用的工具及脚本)|-- acp (Android "acp" Command)|-- apicheck (api检查工具)|-- applypatch (补丁工具)|-- apriori (预链接工具)|-- atree (tree工具)|-- bin2asm (bin转换为asm工具)|-- check_prereq (检查编译时间戳工具)|-- dexpreopt (模拟器相关工具,具体功能不明)|-- droiddoc (?作用不明,java语言,网上有人说和JDK5有关)|-- fs_config (This program takes a list of files and directories)|-- fs_get_stats (获取文件系统状态)|-- iself (判断是否ELF格式)|-- isprelinked (判断是否prelinked)|-- kcm (按键相关)|-- lsd (List symbol dependencies)|-- releasetools (生成镜像的工具及脚本)|-- rgb2565 (rgb转换为565)|-- signapk (apk签名工具)|-- soslim (strip工具)`-- zipalign (zip archive alignment tool)dalvik目录用于提供Android JAVA应用程序运行的基础————JAVA虚拟机。
dalvik目录 dalvik虚拟机.|-- dalvikvm (main.c的目录)|-- dexdump (dex反汇编)|-- dexlist (List all methods in all concrete classes in a DEX file.)|-- dexopt (预验证与优化)|-- docs (文档)|-- dvz (和zygote相关的一个命令)|-- dx (dx工具,将多个java转换为dex)|-- hit (?java语言写成)|-- libcore (核心库)|-- libcore-disabled (?禁用的库)|-- libdex (dex的库)|-- libnativehelper (Support functions for Android's class libraries)|-- tests (测试代码)|-- tools (工具)`-- vm (虚拟机实现)development目录展开的一个级别的目录如下所示:development|-- apps (Android应用程序的模板)|-- build (编译脚本模板)|-- cmds|-- data|-- docs|-- emulator (仿真相关)|-- host (包含windows平台的一些工具)|-- ide|-- pdk|-- samples (一些示例程序)|-- simulator (大多是目标机器的一些工具)`-- tools在emulator目录中qemud是使用QEMU仿真时目标机器运行的后台程序,skins是仿真时手机的界面。