版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、以下摘自daniel wood的博客:android gps架构分析(gps启动过程图)gps启动过程图(基于google android 2.2代码)下面再贴一张从googlei/o大会文档里面截来的图android gps架构分析-previewandroid gps架构分析daniel wood 20101222转载时请注明出处和作者文章出处:作者:daniel wood-看android的gps模块有两个月了吧,终于可以写点东西出来。首先来看看gps模块的代码结构:framework:1.frameworks/base/location/java/android/location这里主
2、要是用来被app调用的,api包是android.location。2.frameworks/base/location/java/com/android/internal/location这个目录是framework对location服务的内部实现。3.frameworkservicesjavacomandroidserver这个目录只有一个文件|- locationmanagerservice.java是location服务对内部实现的一种封装。jni:frameworks/base/core/jni/android_location_gpslocationprovider.cppjni层
3、只有一个文件,起到承上启下的作用。上层承接framework,下层调用hal层具体硬件抽象实现。hal:hardware abstract layer 硬件抽象层hardwarelibhardware_legacygpshardwarelibhardware_legacyincludehardware_legacygps.hhal层相当于一个linux应用程序接口,通过open,close等操作,操作硬件设备。android的源代码只实现了模拟器的gps接口,具体在文件gps_qemu.c中。在2.2版本中提供了对qcom公司的gps的实现,在以下目录:hardwareqcom下面介绍几个重要
4、的数据结构:1. gpsinterface接口是gps模块中最重要的数据结构,它是底层驱动实现的接口,如果要porting到自己的板子上,就需要实现这些接口。该接口的定义在gps.h中,模拟器实现在gps_qemu.c中。/* represents the standard gps interface. */typedef struct /* opens the interface and provides the callback routines* to the implemenation of this interface.*/int (*init)( gpscallbacks* cal
5、lbacks );/* starts navigating. */int (*start)( void );/* stops navigating. */int (*stop)( void );/* closes the interface. */void (*cleanup)( void );/* injects the current time. */int (*inject_time)(gpsutctime time, int64_t timereference,int uncertainty);/* injects current location from another locat
6、ion provider* (typically cell id).* latitude and longitude are measured in degrees* expected accuracy is measured in meters*/int (*inject_location)(double latitude, double longitude, float accuracy);/* specifies that the next call to start will not use the* information defined in the flags. gps_dele
7、te_all is passed for* a cold start.*/void (*delete_aiding_data)(gpsaidingdata flags);/* fix_frequency represents the time between fixes in seconds.* set fix_frequency to zero for a single-shot fix.*/int (*set_position_mode)(gpspositionmode mode, int fix_frequency);/* get a pointer to extension infor
8、mation. */const void* (*get_extension)(const char* name); gpsinterface;2. gpscallbacks回调函数 这个是回调函数结构体,定义也在gps.h中。它们的实现是在android_location_gpslocationprovider.cpp中,google已经实现了,我们不需要做任何动作。/* gps callback structure. */typedef struct gps_location_callback location_cb;gps_status_callback status_cb;gps_sv_
9、status_callback sv_status_cb;gps_nmea_callback nmea_cb; gpscallbacks;/* callback with location information. */typedef void (* gps_location_callback)(gpslocation* location);/* callback with status information. */typedef void (* gps_status_callback)(gpsstatus* status);/* callback with sv status inform
10、ation. */typedef void (* gps_sv_status_callback)(gpssvstatus* sv_info);/* callback for reporting nmea sentences. */typedef void (* gps_nmea_callback)(gpsutctime timestamp, const char* nmea, int length);3. gpslocation表示locatin数据信息,底层驱动获得location的raw信息,通常是nmea码,然后通过解析就得到了location信息。/* represents a loc
11、ation. */typedef struct /* contains gpslocationflags bits. */uint16_t flags;/* represents latitude in degrees. */double latitude;/* represents longitude in degrees. */double longitude;/* represents altitude in meters above the wgs 84 reference* ellipsoid. */double altitude;/* represents speed in met
12、ers per second. */float speed;/* represents heading in degrees. */float bearing;/* represents expected accuracy in meters. */float accuracy;/* timestamp for the location fix. */gpsutctime timestamp; gpslocation;android gps架构分析(一)android gps架构分析daniel wood 20101222转载时请注明出处和作者文章出处:作者:daniel wood- 介绍完了
13、主体代码结构以及重要的数据结构后,下面来看看gps的定位服务(locationmanager)的启动过程。我总是喜欢追本溯源地从源头去认识事物。因为“人之初,性本善”,从事物的本性去认识事物。locationmanager 这项服务是在systemserver.java 中启动的,也就是系统启动之后,这个服务就已经启动了:systemserver.java frameworkbaseservicesjavacomandroidserver在systemserver.java的init2函数中启动了一个线程来注册android的诸多服务,如:bluetooth service,networkma
14、nagement service,notification manager等,当然也包括location service。systemserver.java frameworksbaseservicesjavacomandroidserverpublic static final void init2() slog.i(tag, entered the android system server!);thread thr = new serverthread();thr.setname(android.server.serverthread);thr.start();在serverthread
15、线程的run函数中locationmanager服务的代码段如下:2.1版本try log.i(tag, location manager);servicemanager.addservice(context.location_service, new locationmanagerservice(context); catch (throwable e) log.e(tag, failure starting location manager, e);2.2的代码中代码段如下形式:try slog.i(tag, location manager);location = new locatio
16、nmanagerservice(context);servicemanager.addservice(context.location_service, location); catch (throwable e) slog.e(tag, failure starting location manager 在run函数的后半部分,是服务对系统的反馈,就是systemready()函数。 locationmanager服务的反馈函数如下:if (locationf != null) locationf.systemready();其中的locationf 是locationmanagerserv
17、ice的final类型,就是一旦赋值,不能更改。final locationmanagerservice locationf = location;哇!locationmanager这项服务的反馈机制只在2.2的代码里面才有啊。2.1中的反馈机制中并没有locationmanager(当然有其他的服务反馈)。而在2.1版本中locationmanagerservice的构造函数如下:locationmanagerservice.java frameworksbaseservicesjavacomandroidserverpublic locationmanagerservice(context
18、 context) super();mcontext = context;thread thread = new thread(null, this, locationmanagerservice);thread.start();if (local_logv) log.v(tag, constructed locationmanager service);2.2版本 public locationmanagerservice(context context) super();mcontext = context;if (local_logv) slog.v(tag, constructed l
19、ocationmanager service);2.1是在构造函数的时候就启动一个自身服务线程。见构造函数。2.2是在反馈机制中通过systemready函数启动自身服务线程。如下:void systemready() / we defer starting up the service until the system is readythread thread = new thread(null, this, locationmanagerservice);thread.start();通过线程run函数,调用initialize函数:public void run()process.se
20、tthreadpriority(process.thread_priority_background);looper.prepare();mlocationhandler = new locationworkerhandler();initialize();looper.loop();发表于: 2010-12-22,修改于: 2010-12-24 09:37, android gps架构分析(二)android gps架构分析daniel wood 20101222转载时请注明出处和作者文章出处:作者:daniel wood-initialize函数locationmanagerservice
21、.javaframeworksbaseservicesjavacomandroidserverprivate void initialize() / create a wake lock, needs to be done before calling loadproviders() belowpowermanager powermanager = (powermanager) mcontext.getsystemservice(context.power_service);mwakelock = powermanager.newwakelock(powermanager.partial_wa
22、ke_lock, wakelock_key);/ load providersloadproviders(); .initialize函数中最重要的就是loadproviders函数了,该函数调用loadproviderslocked,然后loadproviderslocked函数又调用_loadproviderslocked函数。为什么要这么折腾呢?先来看一部分的_loadproviderslocked函数:private void _loadproviderslocked() / attempt to load real providers firstif (gpslocationprov
23、ider.issupported() / create a gps location providergpslocationprovider gpsprovider = new gpslocationprovider(mcontext, this);mgpsstatusprovider = gpsprovider.getgpsstatusprovider();mnetinitiatedlistener = gpsprovider.getnetinitiatedlistener();addprovider(gpsprovider);mgpslocationprovider = gpsprovid
24、er; .注意这个if语句,狠重要,因为在这个语句中得到了hal层的gps接口gpsinterface。就是通过调用gpslocationprovider的issupported()函数才调用到gps.cpphardware/libhardware_legacy/gps中的gps_get_interface()。这个issupported函数才是第一个吃螃蟹的人。(而不是jni层的init函数,这个下面会提到)。gpslocationprovider.cpp frameworksbaselocationjavacomandroidinternallocationpublic static bo
25、olean issupported() return native_is_supported();然而issupported只有一句话,果然是高手,一击必中。然后就调用native方法,也就是jni层定义的方法。native_is_supported函数对于jni层是android_location_gpslocationprovider_is_supported方法。android_location_gpslocationprovider.cpp frameworksbasecorejnistatic jboolean android_location_gpslocationprovider
26、_is_supported(jnienv* env, jclass clazz) if (!sgpsinterface)sgpsinterface = gps_get_interface();return (sgpsinterface != null);前面已经提到jni起到承上启下的作用,gps_get_interface函数属于hal层的调用,在文件gps.cpp中。gps.cpp hardwarelibhardware_legacygpsconst gpsinterface*gps_get_interface()if (sgpsinterface = null)gps_find_hard
27、ware();return sgpsinterface;然后通过gps_find_hardware函数去得到gps接口,下面只模拟器中的gpsinterface。static voidgps_find_hardware( void )#ifdef have_qemu_gps_hardwareif (qemu_check() sgpsinterface = gps_get_qemu_interface();if (sgpsinterface) logd(using qemu gps hardware emulationn);return;#endif#ifdef have_gps_hardwar
28、esgpsinterface = gps_get_hardware_interface();#endifif (!sgpsinterface)logd(no gps hardware on this devicen);gps_qemu.c hardwarelibhardware_legacygpsconst gpsinterface* gps_get_qemu_interface()return &qemugpsinterface;qemugpsinterface的整体实现就在文件gps_qemu.c中。static const gpsinterface qemugpsinterface =
29、qemu_gps_init,qemu_gps_start,qemu_gps_stop,qemu_gps_cleanup,qemu_gps_inject_time,qemu_gps_inject_location,qemu_gps_delete_aiding_data,qemu_gps_set_position_mode,qemu_gps_get_extension,;发表于: 2010-12-22,修改于: 2010-12-24 10:42,已浏览574次,android gps架构分析(三)android gps架构分析daniel wood 20101222转载时请注明出处和作者文章出处:
30、作者:daniel wood-在底层得到gps的接口之后, if (gpslocationprovider.issupported()(在文件locationmanagerservice.java中调用)语句得到true,然后进行下一步操作,在这里new了一个gpslocationprovider对象。代码如下:gpslocationprovider gpsprovider = new gpslocationprovider(mcontext, this);注意gpslocationprovider构造函数里面的两个参数:mcontext, this。下面来看看gpslocationprovi
31、der的构造函数的前面几句:public gpslocationprovider(context context, ilocationmanager locationmanager) mcontext = context;mlocationmanager = locationmanager;mnihandler = new gpsnetinitiatedhandler(context, this); . 在gpslocationprovider类里面的成员变量mlocationmanager是构造函数的第二个参数,就是说是locationmanagerservice对象。这一点在这里先明确。接
32、着看_loadproviderslocked函数。private void _loadproviderslocked() / attempt to load real providers firstif (gpslocationprovider.issupported() / create a gps location providergpslocationprovider gpsprovider = new gpslocationprovider(mcontext, this);mgpsstatusprovider = gpsprovider.getgpsstatusprovider();m
33、netinitiatedlistener = gpsprovider.getnetinitiatedlistener();addprovider(gpsprovider);mgpslocationprovider = gpsprovider;/ create a passive location provider, which is always enabledpassiveprovider passiveprovider = new passiveprovider(this);addprovider(passiveprovider);menabledproviders.add(passive
34、provider.getname();/ initialize external network location and geocoder servicesresources resources = mcontext.getresources();string servicename = resources.getstring(ernal.r.string.config_networklocationprovider);if (servicename != null) mnetworklocationprovider =new locationproviderp
35、roxy(mcontext, locationmanager.network_provider,servicename, mlocationhandler);addprovider(mnetworklocationprovider);servicename = resources.getstring(ernal.r.string.config_geocodeprovider);if (servicename != null) mgeocodeprovider = new geocoderproxy(mcontext, servicename);updateprov
36、iderslocked();在构造完gpslocationprovider之后将其add到全局变量arraylist mproviders中,备以后调用。在2.2中采取了一种passiveprovider的类,而在2.1中是通过locationproviderproxy代理类的方式。2.1中locationproviderproxy作为gpslocationprovider的代理作用在locationmanagerservice中,而2.2中的passiveprovider感觉这个类是个空壳。有待研究。然后启动了nerwork location和geocoder 两个service。但是可惜的
37、是这两个服务都无法启动,因为他们是通过配置文件conifg.xml frameworkbasecoreresresvalues得到服务的名字,然后启动服务的。但是在这个配置文件中,两个服务的名字都是null。conifg.xml frameworkbasecoreresresvaluesnullnull其实这也导致了,在调用getfromlocationname和getfromlocation两个函数时提示“service not available”,这个google android 2.2的bug。_loadproviderslocked函数的最后一句是调用updateprovidersl
38、ocked函数,仍然在locationmanagerservic.java文件中。locationmanagerservic.javaprivate void updateproviderslocked() for (int i = mproviders.size() - 1; i = 0; i-) locationproviderinterface p = mproviders.get(i);boolean isenabled = p.isenabled();string name = p.getname();boolean shouldbeenabled = isallowedbysett
39、ingslocked(name);if (isenabled & !shouldbeenabled) updateproviderlistenerslocked(name, false); else if (!isenabled & shouldbeenabled) updateproviderlistenerslocked(name, true); 从上面_loadproviderslocked函数的代码来看,在mproviders这个arraylist 中有两个元素(这一点未求证),一个是gpsprovider,另一个是passiveprovider。gpsprovider是 gpsloc
40、ationprovider类型的,它的isenabled函数返回的是false,因为它并没有被enable。而 passiveprovider是passiveprovider类型,它总是enable的。所以gpsprovider会调用else语句中的updateproviderlistenerslocked(name, true)函数。我们主要分析这个else语句,对于passiveprovider不做分析。private void updateproviderlistenerslocked(string provider, boolean enabled) int listeners = 0
41、;locationproviderinterface p = mprovidersbyname.get(provider);if (p = null) return;arraylist deadreceivers = null;arraylist records = mrecordsbyprovider.get(provider);if (records != null) final int n = records.size();for (int i=0; in; i+) updaterecord record = records.get(i);/ sends a notification m
42、essage to the receiverif (!record.mreceiver.callproviderenabledlocked(provider, enabled) if (deadreceivers = null) deadreceivers = new arraylist();deadreceivers.add(record.mreceiver);listeners+;if (deadreceivers != null) for (int i=deadreceivers.size()-1; i=0; i-) removeupdateslocked(deadreceivers.g
43、et(i);if (enabled) /enabled的值是truep.enable();if (listeners 0) p.setmintime(getmintimelocked(provider);p.enablelocationtracking(true); else p.enablelocationtracking(false);p.disable();我们只关注主体部分代码,就是在if(enabled)这个语句段里面,启动了gps的服务,具体将在下一篇进行分析。 发表于: 2010-12-24,修改于: 2010-12-24 13:29,已浏览852次,有评论5条android g
44、ps架构分析(四)android gps架构分析daniel wood 20101224转载时请注明出处和作者文章出处:作者:daniel wood-通过调用gpslocationprovider类的enable和enablelocationtracking函数就把gps的locationmanager服务启动起来了。下面对这两个函数进行分析。首先是enable函数。gpslocationprovider.javapublic void enable() synchronized (mhandler) mhandler.removemessages(enable);message m = me
45、ssage.obtain(mhandler, enable);m.arg1 = 1;mhandler.sendmessage(m);对了,这个要提一点,在2.2中加入了一个providerhandler类(extends handler),这个在2.1中是没有的,其实是换汤不换药的,对于函数调用的过程来说没有本质的改变。对于handler的机制我还没有研究过。public void handlemessage(message msg)switch (msg.what) case enable:if (msg.arg1 = 1) handleenable(); else handledisabl
46、e();break;case enable_tracking:handleenablelocationtracking(msg.arg1 = 1);break;.在handlemessage函数中,定义了各种message对应的处理函数。对于enable消息还带有一个参数,enable函数里面带的参数值为1,所以调用handleenable函数。private void handleenable() if (debug) log.d(tag, handleenable);if (menabled) return;menabled = native_init();if (menabled) if (msuplserverhost != null) native_set_agps_server(agps_type_s
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026五年级数学下册 找次品素养测评
- 2026年医疗废物应急试题及答案
- 2026三年级数学下册 位置与方向合作学习
- 抗生素合理使用与感染控制
- 校园安全风险防控方案
- 2026五年级数学上册 小数除法解决问题
- 我国会计法律责任制度
- 打假责任制度
- 执行董事权利与责任制度
- 承包生产线用工责任制度
- 《耳鼻咽喉头颈外科学》教学大纲(完整版)
- 如愿二声部合唱简谱文档
- MT 425-1995隔绝式化学氧自救器
- GB/T 31089-2014煤矿回采率计算方法及要求
- GB/T 18046-2008用于水泥和混凝土中的粒化高炉矿渣粉
- 临床检验基础各章节练习题及思考题
- 2022中国电信校园招聘笔试题目
- 《医学细胞生物学》本科课件02章 细胞生物学的研究方法
- 环刀法压实度自动计算程序灰土
- 友邦保险基本法ppt课件
- 丽声北极星分级绘本第一级下Prince-Seb's-Pet课件
评论
0/150
提交评论