Android开发分为应用开发和系统开发,本文是《浅谈Android应用开发中一些概念的理解》的姊妹篇。
Android系统基于Linux系统搭建,有其自己的特点,虽然系统开发技术通常只有ROM厂商或深度定制才需要,但对于应用开发人员来说,了解底层的一些实现,对于更好的应用Android应用框架来开发应用,是大有裨益的。下面总结一下我在Andriod系统开发学习过程中对一些概念的理解。
1、android系统启动过程:1)linux系统启动并初始化init进程。2)启动守护进程,如usbd、adbd、debuggered、rild等。3)启动dalvik虚拟机进程。4)启动运行时进程,提供Binder服务,启动服务器管理器进程。5)启动原生服务并注册到服务管理器。6)启动各种系统服务并注册到服务管理器。7)等待其他应用程序的加载启动。
2、android从上到下分为4层:Java应用程序、Java应用程序框架、C/C++系统运行时库、HAL硬件抽象层、Linux内核,通常从上到下的调用过程为:Java应用程序通过Binder调用应用程序框架的Java服务,Java服务通过JNI调用系统运行时库的C/C++原生服务,C/C++原生服务动态加载HAL库,HAL库进而通过系统调用或设备IO访问内核。
3、PC上的adb工具通过与设备上的adbd服务连接,可以对设备进行管理或者获取状态。
4、传统的IPC数据传输需要2次拷贝,共享内存虽然不需数据拷贝,但控制复杂,另外为了确保通信的安全性,Android定义了Binder的进程间通信方式,只需要1次数据拷贝,通过mmap内存映射内核缓冲区到接收方缓冲区,所以只需发送方缓冲区拷贝到内核缓冲区1次即可实现通信。Binder是客户端和服务端都继承同一套IBinder接口来实现类似远程调用的机制,工作流程为:服务端向服务管理器注册服务,客户端向服务管理器查询服务并获取服务代理,客户端调用服务代理,服务代理通过Binder库访问内核驱动,把Binder请求发送到服务端,服务端执行完请求并返回结果,客户端通过服务代理取得执行结果。
5、NDK支持Java使用JNI调用C代码,先用Java定义JNI接口,然后用C代码实现接口并编译成so库,然后在Java中载入这个so库,就可以调用C代码实现了。
6、Ashmen实现了一套基于mmap的进程间内存共享机制,当进程用Ashmen分配了一块内存,但是其中一部分没有使用,可以将其物理页面释放掉,如果进程后续还需要使用这部分内存,可以直接访问,在缺页中断中会重新为这部分内存分配物理页面。
7、Low Memory Killer优化了linux原有的OOM机制,在系统内存小于临界值时根据一定的策略kill掉进程来释放内存,这个策略是内存描述符中oom_adj值越大或占用物理内存越多的进程会优先被kill掉。
8、Logger通过内核驱动为用户空间的C/C++和Java开发提供了日志服务,并提供应用层工具logcat来读取内核中缓存的日志。
9、电源管理分为三种状态,earlysuspend状态时设备进入低功耗状态,suspend状态时除电源管理外其他外围模块和CPU均不工作,内存保持自动刷新,hibernation状态时内存写入磁盘,系统关机。
10、HAL有两种使用方式:1)运行时库直接载入HAL模块,通过HAL模块来调用驱动,这种方法有HAL模块被载入多个进程的缺点。2)运行时库向HAL取得HAL模块的stub,然后通过stub来调用驱动。HAL的由来:1)由于一些硬件厂商不想开源驱动,但是linux内核必须得开放源码,所以谷歌定义了HAL层,硬件厂商可以把驱动的主要逻辑放在HAL层并不开源,内核驱动只放最基本的寄存器读写。2)向应用层提供统一的接口,不同厂商的驱动不同,移植到Android系统后,各厂商不用为Android重新开发一套驱动,只要按照HAL接口定义为自己的驱动做适配就可以了。
11、Dalvik虚拟机的特点:1)要通过dx工具把class字节码转换成专有的dex字节码。2)能够同时运行多个虚拟机实例,一个虚拟机实例对应于一个进程和一个应用程序。3)支持JIT技术,虚拟机在解释代码时会把需要反复执行的代码段进行编译,然后放入内存中。
(完)