上面介绍了 sGpsInterface->init(&sGpsCallbacks)中sGpsCallbacks的作用,但是init函数调用还未进行剖析:
sGpsInterface定义如下:
static const GpsInterface* sGpsInterface = NULL;
它是在Android_location_GpsLocationProvider_class_init_native函数初始化的,该函数在GpsLocationProvider中通过static方式预加载:
[java]
err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module); if (err == 0) { hw_device_t* device; //通过open调用,在native层分配了一个 gps_device_t的空间,并传递回来。 err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device); if (err == 0) { //这个强制转换是因为 gps_device_t中第一个item是一个 hw_device_t。 //并且在native中确实是分配的gps_device_t空间 gps_device_t* gps_device = (gps_device_t *)device; sGpsInterface = gps_device->get_gps_interface(gps_device); } }可见这个 sGpsInterface是从hwModule中获取的。来看看get_gps_interface函数:
[java]
static int open_gps(const struct hw_module_t* module, char const* name, struct hw_device_t** device) { struct gps_device_t *dev = malloc(sizeof(struct gps_device_t)); if (dev == NULL) { LOGE("gps device can not malloc memery!"); return -ENOMEM; } memset(dev, 0, sizeof(*dev)); dev->common.tag = HARDWARE_DEVICE_TAG; dev->common.version = 0; dev->common.module = (struct hw_module_t*)module; dev->common.close = close_gps; //注意一个有参 一个无参 dev->get_gps_interface = gps_get_hardware_interface; *device = (struct hw_device_t *)dev; return 0; } const GpsInterface *gps_get_hardware_interface() { return &ubloxGpsInterface; } /*gps interface struct*/ static const GpsInterface ubloxGpsInterface = { .size = sizeof(GpsInterface), .init = ublox_gps_init, .start = ublox_gps_start, .stop = ublox_gps_stop, .cleanup = ublox_gps_cleanup, .inject_location = ublox_gps_inject_location, .delete_aiding_data = ublox_gps_delete_aiding_data, .set_position_mode = ublox_gps_set_position_mode, .get_extension = ublox_gps_get_extension, }; static int ublox_gps_init(GpsCallbacks* callbacks) { UbloxGpsData *gps_data = &ublox_gps_data; //ublox gps support MS-based A-GPS, fix in the gps terminal callbacks->set_capabilities_cb(GPS_CAPABILITY_SCHEDULING | GPS_CAPABILITY_MSB); pthread_mutex_init(&gps_data->deferred_action_mutex, NULL); pthread_cond_init(&gps_data->deferred_action_cond, NULL); agps_state->used_proxy = 0; gps_data->gps_callbacks = *callbacks; gps_data->thread_start = 0; LOGD("gps finishes initialization"); return 0; }所以 sGpsInterface实际上指向了native层的 ubloxGpsInterface。调用其init函数,将JNI空间的回调函数传递到了native空间。
应用层通过调用
[java]
Settings.Secure.setLocationProviderEnabled( resolver, LocationManager.GPS_PROVIDER, desiredState);来enable或者Disable位置服务。