Android GPS架构分析
Daniel Wood 20101222
转载时请注明出处和作者
文章出处:http://danielwood.cublog.cn
作者:Daniel Wood
--------------------------------------------------------------------------------
在底层得到
gps
的接口之后,
if (GpsLocationProvider.isSupported()
)
(在文件
LocationManagerService.java
中调用)语句得到
true
,然后进行下一步操作,在这里
new
了一个
GpsLocationProvider
对象。代码如下:
GpsLocationProvider gpsProvider =
new
GpsLocationProvider(
mContext,
this
)
;
|
注意
GpsLocationProvider
构造函数里面的两个参数:
mContext, this
。下面来看看GpsLocationProvider的
构造函数的前面几句:
public
GpsLocationProvider(
Context context,
ILocationManager locationManager)
{
mContext =
context;
mLocationManager =
locationManager;
mNIHandler =
new
GpsNetInitiatedHandler(
context,
this
)
;
...
}
|
在
GpsLocationProvider
类里面的成员变量
mLocationManager
是构造函数的第二个参数,就是说是
LocationManagerService
对象。这一点在这里先明确。
接着看_loadProvidersLocked函数。
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
(
)
;
}
|
在构造完GpsLocationProvider之后将其add到全局变量ArrayList<LocationProviderInterface> mProviders中,备以后调用。
在2.2中采取了一种PassiveProvider的类,而在2.1中是通过LocationProviderProxy代理类的方
式。2.1中
LocationProviderProxy作为GpsLocationProvider的代理作用在LocationManagerService中,而2.2中的PassiveProvider
感觉这个类是个空壳。。。。。。。。有待研究。
然后启动了nerwork location和geocoder 两个service。但
是可惜的是这两个服务都无法启动,因为他们是通过配置文件
conifg.xml
[framework/base/core/res/res/values]
得到服务的名字,然后启动服务的。但是在这个配置文件中,两个服务的名字都是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>
|
其实这也导致了,在调用GetFromLocationName和GetFromLocation两个函数时提示“Service not Available”,这个google Android 2.2的bug。
_loadProvidersLocked函数的最后一句是调用
updateProvidersLocked
函数,仍然在
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
函数的代码来看,在mProviders这个
ArrayList
中有两个元素(这一点未求证),一个是gpsProvider,另一个是passiveProvider。gpsProvider是
GpsLocationProvider类型的,它的isEnabled函数返回的是false,因为它并没有被enable。而
passiveProvider是PassiveProvider类型,它总是enable的。所以gpsProvider会调用else语句中的updateProviderListenersLocked(
name
,
true)
函数。我们主要分析这个else语句,对于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
(
)
;
}
}
|
我们只关注主体部分代码,就是在if(enabled)这个语句段里面,启动了gps的服务,具体将在下一篇进行分析。