Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> [Android的系統移植與平台開發]Sensor HAL框架分析[2]

[Android的系統移植與平台開發]Sensor HAL框架分析[2]

編輯:Android開發實例

1.1 Sensor應用程序框架

這部分對於上層寫應用的朋友來比較熟悉,我們通過一個簡單的應用來分析框架層和底層的實現。

通常編寫一個傳感器的應用程序有以下步驟:

l 通過調用 Context.getSystemService(SENSOR_SERVICE)獲得傳感器服務,實現返回的是封裝了SensorService的SensorManager對象

l 調用SensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION)來獲得指定類型的傳感器對象,方便獲得傳感器的數據

l 通過SensorManager.registerListener注冊SensorEventListener監聽器,監聽獲得的傳感器對象,當傳感器數據提交上來時,能被應用程序得到

l 實現監聽器裡傳感器上報數據的具體操作

由編寫應用程序的步驟可知,所有程序的操作都和SensorManager有關。在開始分析具體實現之前我們先來談談SensorManager概念。

1) Android Manager機制

Manager中文直譯是處理者,經理,管理人,總而言之,管事的人。用我的話說就是:有權有錢,屁事不干,指點江山,NB朝天。在Android的服務框架裡Manager被安排作為經理人、領導,它負責自己管轄區的所有操作。類似於公司裡的行政部門,它是一個純粹非盈利服務部門,行政部門經理自己從來不干活,天天指揮別人干這干那,如果其它部門要想使用行政部門的服務,先要向行政經理提申請,申請通過了,安排具體人員為你服務。我們分析的是Sensor服務,Sensor服務用戶程序不能直接訪問,要通過SensorManager來訪問,也就是說SensorManager是SensorService提供服務接口的封裝。

通常在Android的Manager裡都會維護對其管理Service的引用,用戶程序提出Service操作申請,Manager將操作申請交由其管理的Service處理,然後將處理結果再交給用戶程序或回調用戶注冊的監聽接口。

總結:

1) Manager是應用程序直接面對的接口

2) Manager裡維護對應的Service

3) 應用程序不能直接訪問Service

為什麼要這麼設計??

使用Manager機制的好處是顯而易見的:

l Service是服務,服務是所有應用共享,不能屬於某一個具體的進程,即:Android程序。

l 基於第一點,Android應用與Service在不同進程,它們之間必然要進行通信,要使用IPC,即:進程間通信,而框架的作用是讓應用程序快速開發提供API,不可能讓進程間通信的代碼出現在Android應用中,這些所謂的後台操作不能讓程序開發者感知到,即:隱藏通信手段與細節。

既然如此,那Google就給我們寫一個Manager類,把共享服務隱藏起來,只暴露操作接口,操作細節,IPC細節統統後台去。

OK,理解了這個,可以看得出來,我們的之前寫的LedHAL是如此的弱智,如此的沒有規范,如此的不考慮框架設計,如此的不復用代碼,如此…,太多了,沒有辦法,慢慢在後面再優化吧,差不多了,開始吧。

前面說了,使用Sensor服務要用SensorManager,讓我們來看看一個簡單應用的代碼,再逐漸展開。

public class SensorAppDemoActivity extends Activity implementsSensorEventListener{

private TextViewmTextView;

/** Calledwhen the activity is first created. */

@Override

public voidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

mTextView= (TextView) findViewById(R.id.mTextView);

// 得到SensorManager

SensorManager sm = (SensorManager)this.getSystemService(SENSOR_SERVICE);

// 獲得指定類型的傳感器對象

SensortempSensor = sm.getDefaultSensor(Sensor.TYPE_TEMPERATURE);

// 注冊傳感器對象的監聽器

sm.registerListener(this, tempSensor, SensorManager.SENSOR_DELAY_NORMAL);

}

 

@Override

public voidonAccuracyChanged(Sensor sensor, int accuracy) {

// TODOAuto-generated method stub

// 未實現該方法

}

 

@Override

public void onSensorChanged(SensorEvent event) {

// TODOAuto-generated method stub

mTextView.setText("Currenttemperature is :" + event.values[0]);

}

}

上面代碼很簡單,得到溫度傳感器對象後,注冊傳感器事件監聽器,當數據變化時在Activity上的TextView上顯示溫度。

現在我們分析每個步驟框架的實現:

先來看Context.getSystemService(SENSOR_SERVICE)。

2) 獲得Sensor系統服務

上面代碼裡getSystemService(String)是在當前Activity裡直接調用的,說明它不是Activity的方法就是其父類的方法,按照繼承關系向上查找:

@frameworks/base/core/java/android/app/ContextImpl.java

@Override

public Object getSystemService(String name) {

ServiceFetcherfetcher = SYSTEM_SERVICE_MAP.get(name);

returnfetcher == null ? null : fetcher.getService(this);

}

這是什麼?我恨Android新版本的代碼,沒有老版本的看著簡單。先來看下SYSTEM_SERVICE_MAP是什麼東西,看樣子像映射關系:

private static final HashMap<String,ServiceFetcher> SYSTEM_SERVICE_MAP =

newHashMap<String, ServiceFetcher>();

SYSTEM_SERVICE_MAP其實是一個哈希鍵值映射表,其Key為String類型,Value為ServiceFetcher類型,而我們獲得服務時通過服務名來查找一個ServiceFetcher類型,並返回ServiceFetcher.getService()的結果作為SensorManager。

static class ServiceFetcher {

intmContextCacheIndex = -1;

 

publicObject getService(ContextImpl ctx) {

// mServiceCache是ArrayList<Object>類型對象

ArrayList<Object> cache =ctx.mServiceCache;

Object service;

synchronized (cache) {

// 對於新創建的Activity mServiceCache裡沒有元素,所以size為0

if (cache.size() == 0) {

// Initialize the cache vector on first access.

// At this point sNextPerContextServiceCacheIndex

// is the number of potential services that are

// cached per-Context.

// sNextPerContextServiceCacheIndex為每個Android服務的索引值

for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {

cache.add(null); // 添加null對象

}

}else { // size不為0的時候,即,之前已經調用過getSystemService

service = cache.get(mContextCacheIndex);

if (service != null) {

return service; // 直接拿到之前添加的對象返回

}

}

service = createService(ctx); // cache.size=0並且已經添加了一個null對象到cache裡

cache.set(mContextCacheIndex, service); // 設置新創建的服務添加到cache裡

return service; // 返回該服務

}

}

publicObject createService(ContextImpl ctx) { // 必須實現的方法

thrownew RuntimeException("Not implemented");

}

}

通過分析代碼可知,在ContextImpl類裡維護了一個ArrayList<Object>對象,其裡面保存著所有注冊的Service對象,並且Service對象的獲得和創建由ServiceFether來封裝,該類就兩個方法:createService和getService,而createService是未實現的方法。createSerive的實現在後面:

private static int sNextPerContextServiceCacheIndex =0;

private static void registerService(String serviceName, ServiceFetcher fetcher){

if(!(fetcher instanceof StaticServiceFetcher)) { //是否為StaticServiceFetcher的對象

fetcher.mContextCacheIndex =sNextPerContextServiceCacheIndex++;

}

SYSTEM_SERVICE_MAP.put(serviceName, fetcher); // 添加到SYSTEM_SERVICE_MAP鍵值表裡

}

static {

registerService(POWER_SERVICE, new ServiceFetcher() {

public Object createService(ContextImpl ctx) {

IBinder b = ServiceManager.getService(POWER_SERVICE);

IPowerManager service = IPowerManager.Stub.asInterface(b);

return new PowerManager(service, ctx.mMainThread.getHandler());

}});

registerService (SENSOR_SERVICE,new ServiceFetcher() {

public Object createService(ContextImpl ctx) {

return new SensorManager(ctx.mMainThread.getHandler().getLooper());

}});

}

好家伙,一下子在靜態初始化語句塊裡通過私有方法registerService注冊了30多個服務,其第二個參數為ServiceFetcher類型,每個注冊的服務都是匿名內部類,都實現了createService方法,在createService方法裡創建了SensorManager對象,該對象和Activity的Looper共享消息隊列。

總結下吧:

用戶程序調用getSystemService(SENSOR_SERVICE),其實現在ContextImpl.java中,在其實實現中從SYSTEM_SERVICE_MAP鍵值表查找與SENSOR_SERVICE鍵對應的對象ServiceFetcher,調用ServiceFetcher.getService方法得到SensorManager對象,而ContextImpl對象裡還維護著一個ServiceCache,如果某個服務被get過一次,就會被記錄在這個所謂緩存裡,ServiceFetcher.getService先查找緩存裡有沒有Cache的Object,如果沒有,則調用自己的createService方法創建這個Object,而createService沒有實現,其在registerService注冊服務時創建ServiceFetcher匿名內部類時實現,並且將注冊的服務添加到SYSTEM_SERVICE_MAP中,在創建SensorManager對象時,它和Activity共享了一個Looper。


 

總而言之,言而總之,在getSystemService(SENSOR_SERVICE)裡,創建了SensorManager對象並且和Activity共享Looper。

轉自:http://blog.csdn.net/mr_raptor/article/details/8090508

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved