文章出处:http://danielwood.cublog.cn
言归正传,分析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