本文转载自: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. 七天学会ASP.NET MVC(七)——创建单页应用 【转】

    http://www.cnblogs.com/powertoolsteam/p/MVC_Seven.html 系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学 ...

  2. 算法之美--2.2 Array

    2016-12-02    00:24:12 利用抽象数据类型实现Array:主要用C++模板实现数组类:体会一个完整的C++类的写法,能顺利写出来的人不多了,特别是对复制构造函数和重载= []运算, ...

  3. 给交换机端口设ip

    先给端口设vlan,再给vlan设ip [H3C]vlan [H3C-vlan100]port GigabitEthernet // <H3C>sy System View: return ...

  4. apue学习笔记(第十七章 高级进程间通信)

    本章介绍一种高级IPC---UNIX域套接字机制,并说明它的应用方法 UNIX域套接字 UNIX域套接字用于在同一台计算机上运行的进程(无关进程)之间的(全双工)通信.相比于因特网套接字,UNIX域套 ...

  5. struts2获取文件真实路径

      CreateTime--2017年8月25日15:59:33 Author:Marydon struts2获取文件真实路径 需要导入: import java.io.FileNotFoundExc ...

  6. js 小总结

    数组操作 创建数组:var standTerm = new Array("维护","维修"); var arr = new Array(); 数组长度:leng ...

  7. 导出数据生成Excel(MVC)

    /// <summary> /// 生成Excel /// </summary> /// <returns></returns> public File ...

  8. hint指定index的深入理解

    http://czmmiao.iteye.com/blog/1480247创建一个表,含有位图index和b-tree index SQL> create table t as select o ...

  9. GitHub上编程语言流行度分析

    GitHub已然是全球最流行的开源项目托管平台,项目数量眼下已经达到了千万级别.Adereth在Counting Stars on GitHub一文提供了一个很有意思的思路,那就是籍GitHub用户通 ...

  10. Zend API:深入 PHP 内核

    Introduction Those who know don't talk. Those who talk don't know. Sometimes, PHP "as is" ...