Android GPS架构分析(四)
ROMan">
言归正传,分析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 controlsocket 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, "GpsEventThreADStarting");
// Exit as soon as disable() is calledinstead of waiting for the GPS to stop.
while (mEnabled) {
// this will wait for an event from theGPS,
// which will be reported viareportLocation or reportStatus
native_wait_for_event();
}
if (DEBUG) Log.d(TAG, "GpsEventThreadexiting");
}
}
run函数中还是需要调用native函数:JNI:android_location_GpsLocationProvider_wait_for_event函数。这个函数就是在一个while循环里面等待事件的触发(由回调函数触发),然后调用GpsLocationProvider类的数据上报函数(Location数据)。这个在后面还会讲到。
static voidandroid_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(booleanenable) {
synchronized (mHandler) {
mHandler.removeMessages(ENABLE_TRACKING);
Message m = Message.obtain(mHandler,ENABLE_TRACKING);
m.arg1 = (enable ? 1 : 0);
mHandler.sendMessage(m);
}
}
同样地,也采取Handler的方式。调用的是handleEnableLocationTracking函数。
private voidhandleEnableLocationTracking(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 instartNavigating()");
return;
}
...
在startNavigating函数中,最有作用的语句就是调用native方法native_start。调用到了JNI层的android_location_GpsLocationProvider_start函数。
android_location_GpsLocationProvider.cpp