|
Android GPS架構(gòu)分析
Daniel Wood 20101222
轉(zhuǎn)載時(shí)請(qǐng)注明出處和作者
文章出處:http://danielwood.
作者:Daniel Wood
--------------------------------------------------------------------------------
在底層得到gps的接口之后, if (GpsLocationProvider.isSupported())(在文件LocationManagerService.java中調(diào)用)語(yǔ)句得到true,然后進(jìn)行下一步操作,在這里new了一個(gè)GpsLocationProvider對(duì)象。代碼如下:
|
GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this);
|
注意GpsLocationProvider構(gòu)造函數(shù)里面的兩個(gè)參數(shù):mContext, this。下面來(lái)看看GpsLocationProvider的構(gòu)造函數(shù)的前面幾句:
|
public GpsLocationProvider(Context context, ILocationManager locationManager) { mContext = context; mLocationManager = locationManager; mNIHandler = new GpsNetInitiatedHandler(context, this);
...
}
|
在GpsLocationProvider類(lèi)里面的成員變量mLocationManager是構(gòu)造函數(shù)的第二個(gè)參數(shù),就是說(shuō)是LocationManagerService對(duì)象。這一點(diǎn)在這里先明確。
接著看_loadProvidersLocked函數(shù)。
|
private void _loadProvidersLocked() { // Attempt to load "real" providers first if (GpsLocationProvider.isSupported()) { // Create a gps location provider GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this); mGpsStatusProvider = gpsProvider.getGpsStatusProvider(); mNetInitiatedListener = gpsProvider.getNetInitiatedListener(); addProvider(gpsProvider); mGpsLocationProvider = gpsProvider; } // create a passive location provider, which is always enabled PassiveProvider passiveProvider = new PassiveProvider(this); addProvider(passiveProvider); mEnabledProviders.add(passiveProvider.getName()); // initialize external network location and geocoder services Resources resources = mContext.getResources(); String serviceName = resources.getString( com.android.internal.R.string.config_networkLocationProvider); if (serviceName != null) { mNetworkLocationProvider = new LocationProviderProxy(mContext, LocationManager.NETWORK_PROVIDER, serviceName, mLocationHandler); addProvider(mNetworkLocationProvider); } serviceName = resources.getString(com.android.internal.R.string.config_geocodeProvider); if (serviceName != null) { mGeocodeProvider = new GeocoderProxy(mContext, serviceName); } updateProvidersLocked(); }
|
在構(gòu)造完GpsLocationProvider之后將其add到全局變量ArrayList<LocationProviderInterface> mProviders中,備以后調(diào)用。
在2.2中采取了一種PassiveProvider的類(lèi),而在2.1中是通過(guò)LocationProviderProxy代理類(lèi)的方式。2.1中LocationProviderProxy作為GpsLocationProvider的代理作用在LocationManagerService中,而2.2中的PassiveProvider感覺(jué)這個(gè)類(lèi)是個(gè)空殼。。。。。。。。有待研究。
然后啟動(dòng)了nerwork location和geocoder 兩個(gè)service。但是可惜的是這兩個(gè)服務(wù)都無(wú)法啟動(dòng),因?yàn)樗麄兪峭ㄟ^(guò)配置文件conifg.xml [framework\base\core\res\res\values]得到服務(wù)的名字,然后啟動(dòng)服務(wù)的。但是在這個(gè)配置文件中,兩個(gè)服務(wù)的名字都是null。
conifg.xml [framework\base\core\res\res\values]
|
<!-- Component name of the service providing network location support. --> <string name="config_networkLocationProvider">@null</string> <!-- Component name of the service providing geocoder API support. --> <string name="config_geocodeProvider">@null</string>
|
其實(shí)這也導(dǎo)致了,在調(diào)用GetFromLocationName和GetFromLocation兩個(gè)函數(shù)時(shí)提示“Service not Available”,這個(gè)google Android 2.2的bug。
_loadProvidersLocked函數(shù)的最后一句是調(diào)用updateProvidersLocked函數(shù),仍然在LocationManagerServic.java文件中。
LocationManagerServic.java
|
private void updateProvidersLocked() { 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); } else if (!isEnabled && shouldBeEnabled) { updateProviderListenersLocked(name, true); } } }
| 從上面_loadProvidersLocked函數(shù)的代碼來(lái)看,在mProviders這個(gè)ArrayList
中有兩個(gè)元素(這一點(diǎn)未求證),一個(gè)是gpsProvider,另一個(gè)是passiveProvider。gpsProvider是
GpsLocationProvider類(lèi)型的,它的isEnabled函數(shù)返回的是false,因?yàn)樗](méi)有被enable。而
passiveProvider是PassiveProvider類(lèi)型,它總是enable的。所以gpsProvider會(huì)調(diào)用else語(yǔ)句中的updateProviderListenersLocked(name, true)函數(shù)。我們主要分析這個(gè)else語(yǔ)句,對(duì)于passiveProvider不做分析。
|
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(); } }
| 我們只關(guān)注主體部分代碼,就是在if(enabled)這個(gè)語(yǔ)句段里面,啟動(dòng)了gps的服務(wù),具體將在下一篇進(jìn)行分析。
|