本文转载自:http://blog.csdn.net/kmesg/article/details/6531577

本文只关注JNI和HAL的接口部分

在jni的android_location_GpsLocationProvider.cpp中,作者定义了一些callback函数和结构体

  1. tatic void location_callback(GpsLocation* location)
  2. {
  3. pthread_mutex_lock(&sEventMutex);
  4. sPendingCallbacks |= kLocation;
  5. memcpy(&sGpsLocation, location, sizeof(sGpsLocation));
  6. pthread_cond_signal(&sEventCond);
  7. pthread_mutex_unlock(&sEventMutex);
  8. }
  9. static void status_callback(GpsStatus* status)
  10. ....
  11. }
  12. static void sv_status_callback(GpsSvStatus* sv_status)
  13. {
  14. ....
  15. }
  16. static void nmea_callback(GpsUtcTime timestamp, const char* nmea, int length)
  17. {
  18. ...
  19. }
  20. GpsCallbacks sGpsCallbacks = {
  21. location_callback,
  22. status_callback,
  23. sv_status_callback,
  24. nmea_callback
  25. };

这个sGpsCallbacks结构体其实就是一个函数指针的结构体,,太bt了。。它在android_location_GpsLocationProvider_init中被传到底层。

  1. if (!sGpsInterface)
  2. sGpsInterface = gps_get_interface();
  3. if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)
  4. return false;

那么你可能很奇怪,这么bt的函数指针用法是为了什么?,再看android_location_GpsLocationProvider_wait_for_event里一段就明白了。

  1. static void android_location_GpsLocationProvider_wait_for_event(JNIEnv* env, jobject obj)
  2. {
  3. pthread_mutex_lock(&sEventMutex);
  4. while (sPendingCallbacks == 0) {
  5. pthread_cond_wait(&sEventCond, &sEventMutex);
  6. }
  7. ...

这里pthread_cond_wait一直阻塞等待一个状态(数据传输过来),而location_callback里的pthread_cond_signal(&sEventCond)就是来唤醒它的。。再看pthread_cond_signal的前一句 memcpy(&sGpsLocation, location, sizeof(sGpsLocation));你估计就幡然醒悟了。。。在jni一层阻塞一事件,然后定义一函数来唤醒,而唤醒这个动作必须在底层(数据传输),所以就定义一个函数指针传下去,让底层调用这个函数来唤醒阻塞的进程。。。

下面是底层调用callback函数,这个callback函数在底层传了无数遍后终于在nmea函数里被调用了

  1. static void
  2. nmea_reader_set_callback( NmeaReader*  r, gps_location_callback  cb )
  3. {
  4. r->callback = cb;
  5. if (cb != NULL && r->fix.flags != 0) {
  6. D("%s: sending latest fix to new callback", __FUNCTION__);
  7. r->callback( &r->fix );
  8. r->fix.flags = 0;
  9. }
  10. }

其实gps数据在底层被读到了NmeaReader这个类里面,fix就是Gps的数据结构体,然后r->callback( &r->fix );就完成了调用。

typedef struct {
    int     pos;
    int     overflow;
    int     utc_year;
    int     utc_mon;
    int     utc_day;
    GpsLocation  fix;
    gps_location_callback  callback;
    char    in[ NMEA_MAX_SIZE+1 ];
} NmeaReader;

android的GPS代码分析JNI如何HAL之间如何设置回调函数【转】的更多相关文章

  1. android手机打电话代码分析

    智能手机的打电话功能是由RIL部分来实现的,见下图: 开始分析Android源代码中的RIL部分. 又上图,以及其他相关资料,我得知在Android中有一个叫rild的守护进程.我猜测此进程与电话的拨 ...

  2. 【Java&Android开源库代码分析】のandroid-async-http の开盘

          在<[Java&Android开源库代码剖析]のandroid-smart-image-view>一文中我们提到了android-async-http这个开源库,本文正 ...

  3. 使用代码给Unity中的动画片段绑定回调函数

    在制作动作游戏的时候,需要播放许多动画,同时还有个需求,那就是动画播放到一定时间时,给一个回调函数,好做对应的状态变更, 我查了一下,发现如果使用的是unity自带的动画系统,要做到这样的话,需要这样 ...

  4. android recover 系统代码分析 -- 选择进入

    最近做Recovery的规范及操作指导文档,花了一些时间将流程搞清. Android利用Recovery模式,进行恢复出厂设置,OTA升级,patch升级及firmware升级.而在进入Recover ...

  5. android recovery 系统代码分析 -- 选择进入【转】

    本文转载自:http://blog.csdn.net/andyhuabing/article/details/9226569 最近做Recovery的规范及操作指导文档,花了一些时间将流程搞清. An ...

  6. [Android]Android焦点流程代码分析

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/7286503.html 通过View的View::focusSe ...

  7. tensorflow笔记:多层LSTM代码分析

    tensorflow笔记:多层LSTM代码分析 标签(空格分隔): tensorflow笔记 tensorflow笔记系列: (一) tensorflow笔记:流程,概念和简单代码注释 (二) ten ...

  8. tensorflow笔记:多层CNN代码分析

    tensorflow笔记系列: (一) tensorflow笔记:流程,概念和简单代码注释 (二) tensorflow笔记:多层CNN代码分析 (三) tensorflow笔记:多层LSTM代码分析 ...

  9. STM32 HAL库的定时器中断回调函数跟串口中断回调函数

    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { //添加回调后的程序逻辑 if (htim->Instance == ...

随机推荐

  1. 九度oj题目&amp;吉大考研10年机试题全解

    吉大考研机试2010年题目 题目一(jobdu1478:三角形的边).    http://ac.jobdu.com/problem.php?pid=1478 给出三个正整数,计算最小的数加上次小的数 ...

  2. Mycat本地模式的自增长分表操作

    Mycat对表t_rc_rule_monitor做分表操作 在mysql上执行(没有t_rc_rule_monitor) DROP TABLE IF EXISTS t_rc_rule_monitor; ...

  3. java基础篇2之枚举

    1.为什么要有枚举 问题:要定义星期几或者性别的变量,该怎么定义? 假设用1-7分别表示星期一到星期日,但有人可能会写成int weekday=0; 枚举就是要让某个类型的变量的取值只能为若干个固定值 ...

  4. ClassPathXmlApplicationContext和FileSystemXmlApplicationContext区别

    ClassPathXmlApplicationContext 默认文件路径是src下那一级classpath:和classpath*:的区别: classpath: 只能加载一个配置文件,如果配置了多 ...

  5. Spring技术笔记(一)

    一.控制反转(IoC)&依赖注入(DI) 1.控制反转: 所谓的控制反转就是应用本身不负责依赖对象的创建及维护, 依赖对象的创建及维护是由外部容器负责的. 这样控制权就由应用转移到了外部容器, ...

  6. java代码实现输出指定以.java结尾的文件的绝对路径

    package 输出指定文件绝对路径; import java.io.File; /* * 需求:请大家把"E:\\JAVA语言"文件夹下全部的java结尾的文件的绝对路径给输出在 ...

  7. bzoj4010【HNOI2015】菜肴制作

    4010: [HNOI2015]菜肴制作 Time Limit: 5 Sec  Memory Limit: 512 MB Submit: 981  Solved: 480 [Submit][Statu ...

  8. vim diff 的使用

    vimdiff 是vim的比较工具可以对两个文件进行差异比较和快速合并 1. 使用vimdiff 比较两个文件 方式一 vimdiff  file_left  file_right   或者  vim ...

  9. idea设置自定义图片

    看图操作哈: 1. 2. 逼格满满:

  10. jxl切割excel文件

    近期在实施一个项目.当中一项工作是处理历史数据. 客户提供过来的数据是excel表格,超过20万条记录,因为目标系统导入限制,每次仅仅能导入大小不超过8M的文件.所以须要对这些数据进行切割处理.在手工 ...