原文地址: http://hi.baidu.com/%CB%EF%CC%EF%BB%AA/blog/item/0f8209a39ef0a980d04358e6.html
言归正传,分析sGpsInterface- > init方法。
gps_qume.c
static int qemu_gps_init( GpsCallbacks* callbacks) { GpsState* s = _gps_state; if ( ! s- > init) gps_state_init( s) ; if ( s- > fd < 0) return - 1; s- > callbacks = * callbacks; return 0; }
在
sGpsInterface- > init中,也就是在qemu_gps_init方法,首先调用了gps_state_init,其次注册了回调函数,再说一次,这个回调函数就是在JNI层实现的,而且有JNI层传下来的函数。
static void gps_state_init( GpsState* state ) { state- > init = 1; state- > control[ 0] = - 1; state- > control[ 1] = - 1; state- > fd = - 1; state- > fd = qemu_channel_open ( & state- > channel, QEMU_CHANNEL_NAME, O_RDONLY ) ; if ( state- > fd < 0) { D( "no gps emulation detected" ) ; return ; } D( "gps emulation will read from '%s' qemud channel" , QEMU_CHANNEL_NAME ) ; if ( socketpair ( AF_LOCAL , SOCK_STREAM , 0, state- > control ) < 0 ) { LOGE( "could not create thread control socket pair: %s" , strerror ( errno ) ) ; goto Fail; } if ( pthread_create ( & state- > thread, NULL , gps_state_thread, state ) ! = 0 ) { LOGE( "could not create gps thread: %s" , strerror ( errno ) ) ; goto Fail; } D( "gps state initialized" ) ; return ; Fail: gps_state_done( state ) ; }
在这个gps_state_init函数中,首先打开串口,然后建立socket通信,然后建立线程监听底层数据上报,分别对应于代码中黄低部分。
3)建立线程监听事件
mEventThread = new GpsEventThread( ) ; mEventThread. start ( ) ;
来看看GpsEventThread的run函数。
public void run ( ) { if ( DEBUG) Log . d( TAG, "GpsEventThread starting" ) ; // Exit as soon as disable() is called instead of waiting for the GPS to stop. while ( mEnabled) { // this will wait for an event from the GPS, // which will be reported via reportLocation or reportStatus native_wait_for_event( ) ; } if ( DEBUG) Log . d( TAG, "GpsEventThread exiting" ) ; } }
run函数中还是需要调用native函数:JNI:android_location_GpsLocationProvider_wait_for_event函数。这个函数就是在一个while循环里面等待事件的触发(由回调函数触发),然后调用GpsLocationProvider类的数据上报函数(Location数据)。这个在后面还会讲到。
static void android_location_GpsLocationProvider_wait_for_event( JNIEnv* env, jobject obj) { pthread_mutex_lock ( & sEventMutex) ; while ( sPendingCallbacks = = 0) { pthread_cond_wait ( & sEventCond, & sEventMutex) ; } . . . }
分析完了enable函数以后就轮到 enableLocationTracking函数了。
GpsLocationProvider.java
public void enableLocationTracking( boolean enable ) { synchronized ( mHandler) { mHandler. removeMessages( ENABLE_TRACKING) ; Message m = Message. obtain( mHandler, ENABLE_TRACKING) ; m. arg1 = ( enable ? 1 : 0) ; mHandler. sendMessage( m) ; } }
同样地,也采取Handler的方式。调用的是handleEnableLocationTracking函数。
private void handleEnableLocationTracking( boolean enable ) { if ( enable ) { mTTFF = 0; mLastFixTime = 0; startNavigating ( ) ; } else { mAlarmManager. cancel ( mWakeupIntent) ; mAlarmManager. cancel ( mTimeoutIntent) ; stopNavigating( ) ; } }
调用startNavigating函数。
private void startNavigating( ) { if ( ! mStarted) { if ( DEBUG) Log . d( TAG, "startNavigating" ) ; mStarted = true; int positionMode; if ( Settings. Secure. getInt ( mContext. getContentResolver( ) , Settings. Secure. ASSISTED_GPS_ENABLED, 1) ! = 0) { positionMode = GPS_POSITION_MODE_MS_BASED; } else { positionMode = GPS_POSITION_MODE_STANDALONE; } if ( ! native_start ( positionMode, false, 1) ) { mStarted = false; Log . e( TAG, "native_start failed in startNavigating()" ) ; return ; }
...
在startNavigating函数中,最有作用的语句就是调用native方法native_start 。调用到了JNI层的android_location_GpsLocationProvider_start函数。
android_location_GpsLocationProvider.cpp