Android GPS架构分析(五)
ROMan">
在startNavigating函数中,最有作用的语句就是调用native方法native_start。调用到了JNI层的android_location_gpsLocationProvider_start函数。
android_location_GpsLocationProvider.cpp
static jboolean android_location_GpsLocationProvider_start(JNIEnv*env, jobject obj, jint positionMode,
jboolean singleFix, jint fixFrequency)
{
int result =sGpsInterface->set_position_mode(positionMode, (singleFix ? 0 :fixFrequency));
if (result) {
return false;
}
return (sGpsInterface->start() == 0);
}
接下去就会调用sGpsInterface接口的实现gps_qemu.c中具体实现的函数。
static int
qemu_gps_start()
{
GpsState* s = _gps_state;
if (!s->init) {
D("%s: called with uninitialized state!", __FUNCTION__);
return -1;
}
D("%s: called", __FUNCTION__);
gps_state_start(s);
return 0;
}
通过向底层发送命令,CMD_START来启动gps。其实这个所谓的底层就是在enable/init函数中启动的等待数据的线程。
static void
gps_state_start( GpsState* s )
{
char cmd = CMD_START;
int ret;
do { ret=write( s->control[0], &cmd,1 ); }
while (ret < 0 && errno ==EINTR);
if (ret != 1)
D("%s: could not send CMD_STARTcommand: ret=%d: %s",
__FUNCTION__, ret, strerror(errno));
}
数据监听线程
static void*
gps_state_thread( void* arg )
{
...
// now loop
for (;;) {
...
if (cmd == CMD_QUIT) {
D("gps thread quitting ondemand");
goto Exit;
}else
if (cmd == CMD_START) {
if (!started) {
D("gps thread startinglocation_cb=%p", state>callbacks.location_cb);
started = 1;
nmea_reader_set_callback( reader,state->callbacks.location_cb );
} }
else if (cmd == CMD_STOP) {
...
}
其实就是注册了一个回调函数,location_cb这个回调函数就是对底层location数据上报的回调函数。
在enableLocationTracking函数调用完成以后,基本上gps服务已经启动完成了,也就是LocationManagerService中的updateProvidersLocked函数的完成,也就是loadProviders函数的完成,也就是initialize函数的完成,也就是run函数的完成,也就是2.2中反馈机制systemReady的完成。
void systemReady() {
// we defer starting up the service untilthe system is ready
Thread thread = new Thread(null, this,"LocationManagerService");
thread.start();
}