文章出处:http://danielwood.cublog.cn
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) { //enabled 的值是true p.enable(); if (listeners > 0) { p.setMinTime(getMinTimeLocked(provider)); p.enableLocationTracking(true); } } else { p.enableLocationTracking(false); p.disable(); } } |
我们只关注主体部分代码,就是在if(enabled)这个语句段里面,启动了gps的服务。
通过调用GpsLocationProvider类的enable和enableLocationTracking函数就把GPS的LocationManager服务启动起来了。下面对这两个函数进行分析。
首先是enable函数。
GpsLocationProvider.java
public void enable() { synchronized (mHandler) { mHandler.removeMessages(ENABLE); Message m = Message.obtain(mHandler, ENABLE); m.arg1 = 1; mHandler.sendMessage(m); } } |
对了,这个要提一点,在2.2中加入了一个ProviderHandler类(extends Handler),这个在2.1中是没有的,其实是换汤不换药的,对于函数调用的过程来说没有本质的改变。对于Handler的机制我还没有研究过。
public void handleMessage(Message msg) { switch (msg.what) { case ENABLE: if (msg.arg1 == 1) { handleEnable(); } else { handleDisable(); } break; case ENABLE_TRACKING: handleEnableLocationTracking(msg.arg1 == 1); break; ... |
在
handleMessage函数中,定义了各种message对应的处理函数。对于ENABLE消息还带有一个参数,enable函数里面带的参数值为1,所以调用handleEnable函数。
private void handleEnable() { if (DEBUG) Log.d(TAG, "handleEnable"); if (mEnabled) return; mEnabled = native_init(); if (mEnabled) { if (mSuplServerHost != null) { native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort); } if (mC2KServerHost != null) { native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort); } // run event listener thread while we are enabled mEventThread = new GpsEventThread(); mEventThread.start(); } else { Log.w(TAG, "Failed to enable location provider"); } } |
在handleEnable函数中中主要做了3件事,不过有一件事情没有做成。先来看看哪三件事:
1)调用了native的初始化方法对gps进行初始化,
2)试图启动agps服务,
3)并启动一个线程去监听事件。
先来说说它没有做成的第二件事,启动agps服务。其实在GpsLocationProvider类构造的时候就试图去读取agps的配置文件"/etc/gps.conf",该文件里面储存着agps的服务器地址以及端口号,但是服务器地址以及端口号都是错误的,所以它基本上无法启动agps服务,而且对模拟器来说agps基本是个鸡肋。关于agps部分可能在以后的以后会提到。下面看它做成的第一和第三件事。
1)调用native方法native_init,就是JNI层的android_location_GpsLocationProvider_init方法,在文件andoird_location_GpsLocationProvider.cpp中。
static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj) { if (!sGpsInterface) sGpsInterface = gps_get_interface(); if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0) return false; ... return true; } |
在初始化函数中会去确认GpsInterface是否已经得到,如果没有得到那么通过gps_get_interface()方法再次去得到,正如其实前面提到的那样该接口已经在android_location_GpsLocationProvider_is_supported函数(第一个吃螃蟹的人)中得到了。然后在第二个if语句中调用初始化方法sGpsInterface->init。
android_location_GpsLocationProvider_init的后半部分,试图通过GpsInterface->get_extension方法去得到gps相关的扩展接口,可是在2.2的模拟器实现中并没有实现这个函数,在gps_qume.c中明显写着return NULL。
gps_qume.c
static const void* qemu_gps_get_extension(const char* name) { return NULL; } |