关注嵌入式安卓物联网行业及人才培养,每日更新,欢迎订阅及留言讨论~~~

作者:倪键树,嵌入式安卓物联网讲师。



1、Android的HAL是为了一些硬件提供商提出的“保护proprietary”的驱动程序而产生的东东,简而言之,就是为了避开Linuxkernal的GPL license的束缚。Android把控制硬件的动作都放到了user space中,而在kernel driver里面只有最简单的读写寄存器的操作,而完全去掉了各种功能性的操作(比如控制逻辑等),这些能够体现硬件特性的操作都放到了Android的HAL层,而Android是基于Aparch的license,因此硬件厂商可以只提供二进制代码,所以说Android知识一个开放的平台,并不是一个开源的平台。

2、Android的HAL的实现需要通过JNI(Java Native Intereface),JNI简单说就是java程序可以调用C/C++写的动态链接库,这样的话,HAL可以使用C/C++语言编写,效率更高。而Android的app可以直接调用.so,也可以通过app->app_manager->service(java)->service(jni)->HAL来调用。第二种方法看上去很复杂,但是更加符合android的架构结构。

3、 1)Kernel Driver

这里的kernel driver相对于linux真正的driver形式上是一样的,也提供open,read,write,ioctl,mmap等接口,就可以只作成往寄存器写操作,至于如何写,为什么写,这些工作都会在HAL层进行的,而一般用户是看不到这些代码的。这也是linux mainstream把android的kernel踢出去的原因,因为这些driver根本无法用在其他的linux平台上。

 2)这一层就位于kernel之上的user space了,一般来说这里需要涉及的是两个结构体:hw_module_t和hw_device_t,第一个结构体是当这个hardware stub被load的时候(hw_get_module())提供的初始化操作,比如提供stub的open(module->methods->open())操作,而第二个结构体是提供该硬件stub具有的操作硬件的接口,,在jollen的mokoid工程里,主要提供打开和关闭led的操作,文件就是led.h和文件led.c,这两个文件最后会被编译成动态链接库,不如libled.so被放到/system/libs/hw/,当service调用hw_get_module(hardware/libhardware/hardware.c)时,会在/system/libs/hw/里面寻找对应的动态链接库,然后提供给service对应的操作接口。


Process and Lifecycle该优先权分五层。下面的列表显示优先权层次顺序:

前景进程

可视进程

服务进程

背景进程

空进程

4、学习不同的语言如何进行协作,尤其是如何实现垃圾回收和多线程。把一个虚拟机实现整合到用C/C++写的程序中。系统环境代指本地操作系统,它有自己的本地库和CPU指令集。本地程序(Native Applications)使用C/C++这样的本地语言来编写,被编译成只能在本地系统环境下运行的二进制代码,并和本地库链接在一起。本地程序和本地库一般地会依赖于一个特定的本地系统环境。只有在同一进程中调用本地代码时,使用JNI。

5、使用JAVA程序调用C函数来打印“、helloworld!",这个过程包含下面几步:

 1.创建一个类(Hello World.java)声明本地方法。在Java代码中声明本地方法必须有“native”标识符,native修饰的方法,在java代码中只作为声明存在。在调用本地方法前,必须首先装载含有该方法的本地库。如HelloWorld.java中所示,置于static块中,在Java VM初始化一个类时,首先执行这部分代码,这可保证用本地方法前,装载了本地库。

 2.使用javac编译源文件HelloWorld.java,产生HelloWorld.class。使用javah -jni来生成C头文件(HelloWorld.h),这个头文件里面包含了本地方法的函数原型。

 3.用C代码写函数原型的实现。

 4.把C函数实现编译成一个本地库,创建Hello-World.dll或者libHello-World.so。

 5.使用java命令运行HelloWorld程序,类文件Hello-World.class和本地库在运行时被加载。

5、开发者使用JNI时最常问到的是JAVA和C/C++之间如何传递数据,以及数据类型之间如何互相映射。

 Java_HelloWorld_print(JNIEnv*,jobject);该函数声明,接受两个参数,而对应的Java代码对该函数的声明没有参数,第一个参数是指向JNIEnv结构的指针;第二个函数,为HelloWorld对象自身,即this指针。JNIEnv是JNI核心数据库之一,地位非常崇高,所有对JNI的调用都要通过此结构体。请注意:jni.h文件必须被包含,该文件定义了JNI所有的函数声明和数据类型。生成本地库的名字,必须与System.loadLibrary("HelloWorld“);待装载库的名字相同。-MD:保证与Win32多线程C库连接(win分为静态、动态、动态多线程。。。C库)-LD:生成动态链接库

6、一对一映射和shared stubs的对比

 shared stubs的主要优点是程序员不必在本地代码中写一大堆的stub函数,一对一映射的优点是高效,因为它不需要太多的附加的数据类型转换.