Android GPS架构分析
Daniel Wood 20101224
转载时请注明出处和作者
文章出处:http://danielwood.cublog.cn
作者:Daniel Wood
--------------------------------------------------------------------------------
分析完了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
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(); }
|
阅读(328) | 评论(0) | 转发(0) |