[android2.3]GPS启动流程及数据流向分析
来源:互联网 发布:武林外传排名知乎 编辑:程序博客网 时间:2024/04/30 03:37
GPS启动流程及数据流向分析:
首先在系统init阶段,会通过ServiceManager addService添加很多的Service,这其中就包含LocationService。
代码在SystemServer.java中:
- try {
- Slog.i(TAG, "Location Manager");
- location = new LocationManagerService(context);
- ServiceManager.addService(Context.LOCATION_SERVICE, location);
- } catch (Throwable e) {
- reportWtf("starting Location Manager", e);
- }
随后调用LocationManagerService的systemReady函数开启一个线程。
- final LocationManagerService locationF = location;
- try {
- if (locationF != null) locationF.systemReady();
- } catch (Throwable e) {
- reportWtf("making Location Service ready", e);
- }
--LocationManagerService.java
- void systemReady() {
- // we defer starting up the service until the system is ready
- Thread thread = new Thread(null, this, "LocationManagerService");
- thread.start();
- }
在 Thread的run函数中为接收消息做好了准备,并且调用了一个initialize函数:
- public void run()
- {
- Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
- Looper.prepare();
- mLocationHandler = new LocationWorkerHandler();
- initialize();
- Looper.loop();
- }
接着看initialize():
- private void initialize() {
- // Create a wake lock, needs to be done before calling loadProviders() below
- PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
- // Load providers
- loadProviders();
- // Register for Network (Wifi or Mobile) updates
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
- // Register for Package Manager updates
- intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
- intentFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
- intentFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
- mContext.registerReceiver(mBroadcastReceiver, intentFilter);
- IntentFilter sdFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
- mContext.registerReceiver(mBroadcastReceiver, sdFilter);
- // listen for settings changes
- ContentResolver resolver = mContext.getContentResolver();
- Cursor settingsCursor = resolver.query(Settings.Secure.CONTENT_URI, null,
- "(" + Settings.System.NAME + "=?)",
- new String[]{Settings.Secure.LOCATION_PROVIDERS_ALLOWED},
- null);
- mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mLocationHandler);
- SettingsObserver settingsObserver = new SettingsObserver();
- mSettings.addObserver(settingsObserver);
- }
其中有两个重要的地方:
1) loadProviders(),会new一个GpsLocationProvider,并将本GpsLocationProvider添加一个ArrayList<LocationProviderInterface>的链 表中。
2) new 一个 SettingsObserver对象,该对象应该是负责在Settings中有数据变化时通知本地程序进行相应处理的功能。其中 SettingsObserver类中实现 了Observer接口,该接口中的update函数应该就是一个回调函数,当Settings中有数据变化时会回调进这个函数:
- private final class SettingsObserver implements Observer {
- public void update(Observable o, Object arg) {
- synchronized (mLock) {
- updateProvidersLocked();
- }
- }
- }
- private void updateProvidersLocked() {
- boolean changesMade = false;
- for (int i = mProviders.size() - 1; i >= 0; i--) {
- LocationProviderInterface p = mProviders.get(i);
- boolean isEnabled = p.isEnabled();
- String name = p.getName();
- boolean shouldBeEnabled = isAllowedBySettingsLocked(name);
- If (isEnabled && !shouldBeEnabled) {
- updateProviderListenersLocked(name, false);
- changesMade = true;
- } else if (!isEnabled && shouldBeEnabled) {
- updateProviderListenersLocked(name, true);
- changesMade = true;
- }
- }
- if (changesMade) {
- mContext.sendBroadcast(new Intent(LocationManager.PROVIDERS_CHANGED_ACTION));
- }
- }
- private void updateProviderListenersLocked(String provider, boolean enabled) {
- int listeners = 0;
- LocationProviderInterface p = mProvidersByName.get(provider);
- if (p == null) {
- return;
- }
- ArrayList<Receiver> deadReceivers = null;
- ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);
- if (records != null) {
- final int N = records.size();
- for (int i=0; i<N; i++) {
- UpdateRecord record = records.get(i);
- // Sends a notification message to the receiver
- if (!record.mReceiver.callProviderEnabledLocked(provider, enabled)) {
- if (deadReceivers == null) {
- deadReceivers = new ArrayList<Receiver>();
- }
- deadReceivers.add(record.mReceiver);
- }
- listeners++;
- }
- }
- if (deadReceivers != null) {
- for (int i=deadReceivers.size()-1; i>=0; i--) {
- removeUpdatesLocked(deadReceivers.get(i));
- }
- }
- if (enabled) {
- p.enable();
- if (listeners > 0) {
- p.setMinTime(getMinTimeLocked(provider), mTmpWorkSource);
- p.enableLocationTracking(true);
- }
- } else {
- p.enableLocationTracking(false);
- p.disable();
- }
- }
可知是在 updateProviderListenersLocked函数中,通过 LocationProviderInterface p调用enable或者disable来开关位置服务。这里会调用到 LocationProviderInterface的子类GpsLocationProvider中的enable或者disable中:
--GpsLocationProvider.java
- public void enable() {
- synchronized (mHandler) {
- sendMessage(ENABLE, 1, null);
- }
- }
handlenable就是ENABLE的消息处理函数:
- private void handleEnable() {
- if (DEBUG) Log.d(TAG, "handleEnable");
- if (mEnabled) return;
- mEnabled = native_init();
- Intent intent = new Intent(LocationManager.GPS_SETTING_ENABLED_CHANGE_ACTION);
- intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, mEnabled);
- mContext.sendBroadcast(intent);
- if (mEnabled) {
- mSupportsXtra = native_supports_xtra();
- if (mSuplServerHost != null) {
- native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort);
- }
- if (mC2KServerHost != null) {
- native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort);
- }
- } else {
- Log.w(TAG, "Failed to enable location provider");
- }
- }
可见这里就开始与native层通信了。
native_init对应jni中的android_location_GpsLocationProvider_init函数,在该函数中调用了
sGpsInterface->init(&sGpsCallbacks),
而 sGpsCallbacks定义如下:
- GpsCallbacks sGpsCallbacks = {
- sizeof(GpsCallbacks),
- location_callback,
- status_callback,
- sv_status_callback,
- nmea_callback,
- set_capabilities_callback,
- acquire_wakelock_callback,
- release_wakelock_callback,
- create_thread_callback,
- request_utc_time_callback,
- };
这是将jni的一些函数作为参数传递到native c 空间中去,这样在native c中如果有可用数据将通过回调的方式调用到jni中的函数。简单的看一下 location_callback的定义:
- static void location_callback(GpsLocation* location)
- {
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- env->CallVoidMethod(mCallbacksObj, method_reportLocation, location->flags,
- (jdouble)location->latitude, (jdouble)location->longitude,
- (jdouble)location->altitude,
- (jfloat)location->speed, (jfloat)location->bearing,
- (jfloat)location->accuracy, (jlong)location->timestamp);
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
- }
其中有定义:
static jmethodID method_reportLocation;并且:
method_reportLocation = env->GetMethodID(clazz, "reportLocation","(IDDDFFFJ)V");
可见jni中的callback函数其实又回调掉了java空间(Framework)中的 reportLocation函数,这便是整个GPS框架的数据流向结构了。所有的数据都是通过回调的方式通知上层:
nativeC通过回调通知JNI,JNI通过回调通知Framework。这应该是gps整个框架最重要的部分吧,理解了数据流向,其他的应该都简单了。
因为代码授权方面的原因,关于native的代码就分析到这里。
最后应用层通过调用
- Settings.Secure.setLocationProviderEnabled(
- resolver,
- LocationManager.GPS_PROVIDER,
- desiredState);
来enable或者Disable位置服务。
kuangkondy@gmail.com
2011,12
原文地址http://blog.csdn.net/kondykuang/article/details/7315482
,感谢作者分享,让我这个android菜鸟收货不小
- [android2.3]GPS启动流程及数据流向分析
- [android2.3]GPS启动流程及数据流向分析
- [android2.3]GPS启动流程及数据流向分析
- GPS启动流程及数据流向分析
- android2.3 gps 架构流程
- Yii数据的流向及处理分析
- hadoop之从数据流向角度分析MapReduce流程
- android2.3 gps 调用流程以及与android2.2 gps的一些区别
- android soundrecorder之三 录音流程及数据流向
- android soundrecorder之三 录音流程及数据流向
- Android_ics_stagefright框架数据流向分析
- porting gps to android2.3
- porting gps to android2.3
- GPS 研究(Android2.3)
- libstagefright openmax编解码数据流向分析
- [总结]2。消息流向及响应分析
- Openwrt启动流程及启动脚本分析
- Openwrt启动流程及启动脚本分析
- 我的助理辞职了 -- 做一个有心的人
- 今天在CSDN黑马程序员训练营的分享
- silverlight如何更新
- java中的IO与NIO
- unity3d 基础入门
- [android2.3]GPS启动流程及数据流向分析
- 手机远控电脑设计
- C# 多线程断点续传
- Yii: 日期和时间控件的使用
- ThreadPool,WaitCallback,QueueUserWorkItem
- 后缀数组 poj3693
- 从零开始学习iphone开发课程
- 关于java中“\”转义的问题
- Cool modes in Emacs