原文地址: http://hi.baidu.com/%CB%EF%CC%EF%BB%AA/blog/item/1179e2e802d4023263d09fe3.html
在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_START command: 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 on demand" ) ; goto Exit ; } else
if ( cmd = = CMD_START) {
if (!started) { D("gps thread starting location_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 until the system is ready Thread thread = new Thread ( null , this , "LocationManagerService" ) ; thread . start ( ) ; }