androidGPS驱动( 四 )


下面分步来看下,jni是如何工作的 。
首先是.cpp这里会调用到
.cpp的注册函数
,而这个注册函数就注册了应用层的的jni 。他会调用下面这个注册函数 。具体各个参数含义,第一个是env,是jni技术的主要结构体,第二个参数就是所要注册的java服务程序的包 。最后一个是方法的回调函数了 。
[html] view plain copy
hods(env,"com////",,NELEM());
下面的是方法的一些函数 。
[html] view plain copy
[]={{"","()V",(void*)},{"","()Z",(void*)},{"","()Z",(void*)t},{"","()V",(void*)anup},{"mode","(IIIII)Z",(void*)},{"","()Z",(void*)rt},{"","()Z",(void*)p},…………………………};
对于这个做一些简单的解释吧: 。
第一个参数name是在java服务层定义的函数 。具体可以看
/base//java/com////.java下的代码 。
这个稍后分析 。
第二个参数是java服务层调用jni层的参数,具体的可以先看下面这个表:
[html] view plain copy
字符Java类型C类型t
数组则以"["开始,用两个字符表示
[html] view plain copy
[[][[][[][[][[][[][[][n[]
实际上这些字符是与函数的参数类型一一对应的 。
"()"中的字符表示参数,后面的则代表返回值 。例如"()V" 就表示void Func();
"(II)V"表示 void Func(int, int);
上面的都是基本类型 。如果Java函数的参数是class,则以"L"开头,以";"结尾中间是用"/" 隔开的包及类名 。而其对应的C函数名的参数则为. 一个例外是类,其对应的类为
[html] view plain copy
Ljava/lang/;/net/;
如果JAVA函数位于一个嵌入类,则用$作为类名间的分隔符 。
例如"(Ljava/lang/;/os/$;)Z"
由此,上面写函数的参数也知道了 。
第三个变量fnPtr是函数指针,指向C函数,也就是在jni的cpp代码中的 。
而jni和java代码的交互可以看下图所示:
其实,java层和jni层都是可以互相调用的,而具体的java层调用jni的方法就是声明的方法;jni调用java的话,要先获取java层的方法id,然后通过()等回调函数实现 。

androidGPS驱动

文章插图
有了以上的知识点作为基础的话,那么现在来分析下GPS的jni代码了 。
1、首先是这个函数了 。
[html] view plain copy
n=env->(clazz,"","()V");……………………………………e=env->(clazz,"","()V")
他先是获取所有的方法id 。然后调用hw模块,也就是上面hal层编译的gps.*.so链接库
[html] view plain copy
err=(ID,(**)&);
然后调用了hal层的gps的open函数了 。
[html] view plain copy
err=->->open(,ID,&);
获取接口 =->();
因为是gps不是agps所以
[html] view plain copy
=(e*)->();
2、接着便是t这个初始化函数了 。
该函数主要是调用了
[html] view plain copy
if(&&->init(&)!=0)=NULL;
这个函数的函数指针init就调用到hal层的init函数 。也就是函数了 。
这里传进来了函数了 。
具体如下:
[html] view plain copy
backs={(),,//回调位置信息,//回调状态信息,//回调sv状态信息,//上报nema信息lback,//回调告知框架层GPS的性能lback,//获取GPS锁,不进行休眠lback,//释放GPS锁ck,//创建线程,可以调用的代码lback,//获取utc时间};
具体函数可以看下面:
[html] view plain copy
(*){*env=::();env->(,n,->flags,()->,()->,()->,()->speed,()->,()->,(jlong)->);(env,);}
这里会调用n这个方法,这个方法是在java服务层调用的 。这里通过函数调用了java 的函数 。
[html] view plain copy
lback(*){*env=::();env->(,,->);(env,);}(*){*env=::();(&,,());env->(,s);(env,);}ack(,*nmea,){*env=::();////=nmea;=;env->(,,);(env,);}(){LOGD("lback:%ld\n",);*env=::();env->(,,);(env,);}(){(,);}获取GPS的锁(){();}释放了GPS的锁(){*env=::();env->(,e);(env,);}更新时间(*name,void(*start)(void*),void*arg){()::(name,start,arg);}创建线程 。