Android系统移植(五)


目的:Android系统中,用实现好的APK通过JNI接口去操作某个驱动节点,实现open,read.write,ioctl等操作!而在上一章节中我们已经写好一个驱动程序,它是控制LED的亮灭的,并且创建了一个设备节点:/dev/bunflyled,也就是通过 open这个设备节点,可以ioctl操作驱动程序实现LED灯的亮灭控制。


那APK是如何调用到驱动程序进而实现LED的亮灭呢?
首先我们来了解下JNI调用流程:
任何语言直接的交互都必须遵循一定的规则或者协议,只有这样双方才能理解各自的意图。java中定义native函数,对于native函数只需要声明,具体实现由C去实现。也就是说,native函数的实现与声明是分离的,java负责声明,C负责实现。所以java在编译是不会关心具体实现,编译时就不会报错。


那如何调用的呢?在调用之前java是不会关心是否已经实现,只有在调用native方法的时候,去找C生成的动态库,如果找不到动态库,那么native方法就会报错。


Java如何找到C的函数的呢?
java的native函数和C中的函数存在一种映射关系,这个映射关系就是遵循的一种协议或者称为规则。比如,APK的类BunflyActivity中声明了:
native int ledon();
该方法在C中对应的是:
int Java_com_up_BunflyActivity_ledon(JNIEnv *env,jclass thiz)
从上面的对应关系可以看出,在C中的规则就是,包名+类名+方法名,并且中间用下划线分割:
第一个参数env,是JNIenv对象,该对象代表一个java虚拟机所运行的环境,通过它可以访问JVM内部的各种对象;
第二个参数jclass在该方法是静态的情况下是是一个类对象的引用,jclass在该方法是实例的情况下代表的是被调用方法所属类的引用.
有这两个参数,如果native函数里面有多个参数,依次在后面排列。


当java调用native函数时,编译器会向native引擎传递调用者的包名,函数名及参数类型,native引擎根据这些信息决定应该调用具体的哪个函数。


在Android中,native引擎中的AndroidRuntime类提供了一个registerNativeMethods()函数,通过此函数定义java方法和C函数的映射关系。


然后去实现相应的C代码,并生成动态库。
如果想要在java中调用native方法,需要在调用的代码前使用System.loadLibrary("lib_name")去装载该动态库。


当Dalvik载入libXXXX.so这个库时,就会呼叫JNI_OnLoad()函数。在JNI_OnLoad()中注册本地函数,继续调用到AndroidRuntime::registerNativeMethods(),该函数向Dalvik(即AndroidRuntime)注册gMethods[]数组中包含的本地函数了。AndroidRuntime::registerNativeMethods()起到了以下两个作用:
1,registerNativeMethods()函数使得java空间中的Native函数更加容易的找到对应的本地函数。(通过gMethods[]中的函数指针)
2,可以在执行期间进行本地函数的替换。因为gMethods[]数组是一个<java中函数名字,本地函数指针>的对应表,所以可以在程序的执行过程中,多次呼叫registerNativeMethods()函数来更换本地函数的指针,提高程序的弹性。


而当调用native方法ledon()的时候,native引擎会根据映射好的关系调用相应的方法,即int Java_com_up_BunflyActivity_ledon(JNIEnv *env,jclass thiz)方法。


JNI层的代码是用C实现好的,因此这就可以达到我们的目的——控制LED。
在C代码中会调用应用层的open系统调用,它最终会调用到驱动层中的open函数,
打开成功之后返回文件描述符,通过该文件描述符就可以操作相应的设备文件。
最后我们可以通过ioctl来达到控制LED的亮灭。




总结:
应用层调用到native方法时(之前应先调用System.loadLibrary("lib_name")去装载该动态库),会根据映射好的关系调用相应的JNI层代码,在该C代码中包含有系统调用等操作,通过这些操作达到控制LED的亮灭。




未完待续!



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值