Android 系统中 Location Service 的实现与架构

转自http://www.ibm.com/developerworks/cn/opensource/os-cn-android-location/


定位服务是移动设备上最常用的功能之一,下文以 Android 源码为基础,详细分析了 Android 系统中定位服务的架构和实现。 定位服务是 Android 系统提供的一项系统服务,在 Android 系统中,所有系统服务的架构都是类似的。只要明白其中一个,然后再去理解其他是很容易的。 对于 Android 的应用开发人员来说,本文可以帮助他们了解他们所使用的 API 背后的实现。 对于 Android 的系统开发人员来说,本文可以帮助他们更好的了解 Android 系统架构。 关于如何获取 Android 源码,请参阅 Android Source 的官方网站:http://source.android.com/source/downloading.html Android 源码中包含了大量的文件,有些源文件甚至是同名的。为了清楚的指明我们所讨论的文件,本文在提到源码文件的时候都会指明其在 Android 源码树中的路径。

droid.location 包与 API 代码示例

定位服务提供给应用层的 API 位于 android.location 包中,它其中包含的类和接口如表 1 所示:


名称 类型 说明
GpsStatus.Listener 接口 用于接受 GPS 状态改变时的通知。
GpsStatus.NmeaListener 接口 用于接受 Nmea(为海用电子设备制定的格式)信息。
LocationListener 接口 用于接受位置信息改变时的通知。
Address 用于描述地址信息。
Criteria 用于选择 LocationProvider。
Geocoder 用于处理地理位置的编码。
GpsSatellite 用于描述 GPS 卫星的状态。
GpsStatus 用于描述 GPS 设备的状态。
Location 用于描述地理位置信息,包括经度,纬度,海拔,方向等信息。
LocationManager 用于获取和调用定位服务。
LocationProvider 描述 Location Provider 的超类,Location Provider 是真正用来获取位置信息的组件。Location Provider 的实现主要可以分为两类:一种依赖于 GPS 设备,另一种依赖网络状态。

在表 1 中,最重要的类是 LocationManager,这是整个定位服务的入口类。 清单 1 是使用定位服务 API 的代码示例:


				
	 public class MainActivity extends Activity { 
	
	  // 测试使用的日志 Tag 
	  private static final String TAG = "LocationService API Demo"; 
	  // 将在 onCreate 中被初始化
	  private LocationManager locationManager; 
	  // 接受位置更新的监听器
	  protected final LocationListener locationListener = 
	                                  new 			 LocationListener() { 
	
	    // 当位置发生变化时,输出位置信息
	    public void onLocationChanged(Location location) { 
	      Log.d(TAG, "Location changed to: " + getLocationInfo(location)); 
	    } 
	  
	    public void onProviderDisabled(String provider) { 
	      Log.d(TAG, provider + " disabled."); 
	    } 
	  
	    public void onProviderEnabled(String provider) { 
	      Log.d(TAG, provider + " enabled."); 
	    } 
	
	    public void onStatusChanged(String provider, int status, 
	 Bundle extras){ 
	      Log.d(TAG, provider + " status changed."); 
	    } 
	  }; 
	
	  @Override 
	  protected void onCreate(Bundle savedInstanceState) { 
	    super.onCreate(savedInstanceState); 
	    setContentView(R.layout.activity_main); 
	    // 获取 LocationManager 
	    locationManager = (LocationManager)getSystemService(LOCATION_SERVICE); 
	  } 
	  
	  @Override 
	  protected void onResume() { 
	    super.onResume(); 
	    // 指定一个 Provider 
	    String currentProvider = LocationManager.NETWORK_PROVIDER; 
	    Log.d(TAG, "CurrentProvider: " + currentProvider); 
	    // 获取 Provider 最后一个记录的地址信息
	    Location lastKnownLocation = locationManager 
	 .getLastKnownLocation(currentProvider); 
	    if (lastKnownLocation != null) { 
	      Log.d(TAG, "LastKnownLocation: "
	    + getLocationInfo(lastKnownLocation)); 
	    } else { 
	      Log.d(TAG, "Last Location Unkown!"); 
	    } 
	    // 注册监听器接受位置更新
	    locationManager.requestLocationUpdates(currentProvider, 0, 0, 
	 locationListener); 
	  } 
	  
	  @Override 
	  protected void onPause() { 
	    super.onPause(); 
	    // 移除监听器
	    locationManager.removeUpdates(locationListener); 
	    Log.d(TAG, "LocationListener: " + locationListener + " removed."); 
	  } 
	
	  /** 
	   * 将 Location 对象转换成字符串形式方便显示
	   * 
	   * @param location 
	   *            Location 对象
	   * @return 字符串形式的表示
	   */ 
	  private String getLocationInfo(Location location) { 
	    String info = ""; 
	    info += "Longitude:" + location.getLongitude(); 
	    info += ", Latitude:" + location.getLatitude(); 
	    if (location.hasAltitude()) { 
	      info += ", Altitude:" + location.getAltitude(); 
	    } 
	    if (location.hasBearing()) { 
	      info += ", Bearing:" + location.getBearing(); 
	    } 
	    return info; 
	  } 
	 } 
	

这段代码的说明如下: 在 Activity 显示的时候首先尝试获取通过网络定位的 Location Provider 记录的最后一次定位信息,然后在系统中注册一个监听器来监听位置信息的变更,这里的 API 都是使用定位服务最常用的。

整个定位服务的架构如图 1 所示。该结构共分为四层:

  • 最上面是应用层,即 android.location 包中包含的内容,是以 Java 语言提供的 API。
  • 第二层是框架层,这一层包含了系统服务的实现,主要由 Java 语言来实现。
  • 第三层是共享库层,本层由 C 以及 C++ 语言实现 , 框架层与共享库层使用 JNI 进行衔接。
  • 最下面一层是 Linux 内核层 , 整个 Android 系统都是以 Linux 内核为基础的。

从上至下它们是逐层依赖的关系,每层依赖下面一层完成其所需提供的服务。

以下是定位服务的架构图


系统的服务的启动与注册

从图 1 中可以看出,在框架层,实现位置服务的类是 LocationManagerService,这是一个系统服务。 那么 LocationManager 和 LocationManagerService 两者是什么关系,它们是如何关联起来的呢? 想要理解这一点就要先介绍一下 Android 中的 Binder 机制。 在 Android 系统中,系统服务运行在一个专门的进程中,这个进程名称为 system_server。该进程在系统启动的时候便被加载和启动。系统中有一个专门用来管理系统服务的类,它叫做 ServiceManager。这个类负责注册并管理所有的系统服务。 当应用程序想要使用系统服务时,需要通过服务的代理来调用服务。由于客户应用程序运行在自己的进程中,这和 system_server 是两个独立的进程,因此代理需要通过进程间通讯将请求发送到 system_server 进程,由该进程来响应服务,然后再返回结果。整个这个机制称之为 Binder 机制。Binder 机制在 Android 系统中应用非常之广,几乎所有的进程间通讯都是使用该进制完成的。 

图 2 描述了 Binder 机制的请求和响应过程:


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值