曾幾何時,本人寫了一篇Android感應器初探"驚豔整個籃球場"...一轉眼兩年過去了,真是物逝人非,技術更新的快啊,如今都已經4.0巧克力冰激淩了...
0. 總論
本文希望分別從動態角度(應用程式進程)以及靜態角度(架構體系架構)兩方面來理解感應器系統。
1. 上層應用
從編寫應用程式的角度來看,比較簡單,大體分如下4步,便可得到一個感應器即時上報的數值並作處理,
1) 得到感應器服務 getSystemService(SENSOR_SERVICE);
得到一個SensorManager,用來管理分配調度處理Sensor的工作,注意它並不服務運行於後台,真正屬於Sensor的系統服務是SensorService,終端下#service list可以看到sensorservice: [android.gui.SensorServer]。
2) 得到感應器類型 getDefaultSensor(Sensor.TYPE_GRAVITY);
當然還有各種千奇百怪的感應器,可以查閱Android官網API或者源碼Sensor.java。
3) 註冊監聽器 SensorEventListener
應用程式開啟一個監聽介面,專門處理感應器的資料,這個監聽機制比較重要,被系統廣泛使用。
4) 實現監聽器的回呼函數 onSensorChanged, onAccuracyChanged
例如對重力感應器的xyz值經演算法變換得到左右上下前後方向等,就由這個回呼函數實現。
1.1 進程空間
一個應用程式對應一個虛擬機器執行個體,一個進程和一個主線程,通過主線程式控制制四大組件。
要想得到感應器資料,須要開一個子線程,通過pol輪訓的方式監聽底層上報的資料,再由訊息機制把資料發送給主線程處理。
換句話說,應用程式有兩個任務:
1)準備一個監聽介面供主線程接受資料
2)開啟一個子線程接受底層資料並發送到主線程,
而這些有關Sensor的具體任務,全部交給SensorManager統一管理。
1.2 Android SDK API
上層通過SDK API得到Java架構,這裡,應用程式通過AIDL介面遠程調用(RPC)得到SensorManager.
可查閱官網SDK API android.hardware.SensorManager類提供的方法。
簡單粗暴概括地講,上層要拿底層資料,無外乎兩部分,
1)裝置的類型 (控制流程)
getSensorList()得到感應器類型,取得sensorList列表的過程由上至下,java架構->JNI->本地架構 ->標準抽象層->裝置驅動
2) 裝置的資料 (資料流)
registerListener()註冊監聽器的時候會開啟一個線程,其中sensor_data_poll同樣由上至下最後拿到底層資料。
寫到這裡,摘抄別人的一段話...
我們在學習新系統時,首先映入眼帘的就是新概念。新名詞,就如現在我們面臨的Android大量的新名詞,在程式員的世界都是從代碼實踐開始的,是從寫應用開始去涉及。SDK給了我們一個概念,我們就在這個概念架構下,使用SDK給我提供的函數介面,資料結構,初始化過程等,我們最初的接觸到原型就是“HelloWorld”之類的DEMO程式,我們在Hello
world上去使用各種不同的介面函數,對於應用程式員來講,他說看到的系統就是系統調用介面,及其編程開發流程。實際上只要一使用這些介面,就不得不接受一系列的概念,只有在這種概念系統下,我們才能工作。但是,實際上我們卻忽略了這樣的概念系統的理解,只是在編程介面的這個狹窄的空間去理解系統.我們理解系統在形成理解概念的空間只是微小的一角,很少有資料來介紹這種概念系統的形成和理解,編程介面只是這個概念空間一個,對外部的一個表徵。我們可以抽象起來,以介面,協議和行為,來描述系統的情況。SDK API的實質向上層提供了一個語義介面,從而在層間實現了一個轉義過程,同時又成為一個功能的集合體。但是我們很少這樣跳出來看,我們到底是處於一種什麼樣的概念空間,SDK除了調用介面外,還給了我們怎樣一種整體概念?目標系統的基本構架在本質上的東西就是一個概念系統到另一個概念系統的映射。讓我們大腦理解的概念系統映射到電腦能實現的概念域的一個映射。我們假定這個概念域E,機器能夠理解的概念域為M,我們的軟體工程要做的事情實質就是:EàM領域的一個映射過程。
2 Java架構
上層由getSystemService(SENSOR_SERVICE);得到一個SensorManager執行個體,為上層提供方法。
除了上文的兩個method,SensorManager本身的建構函式很有必要看下,
nativeClassInit(); 在JNI層得到android.hardware.Sensor的JNI環境指標env.
sensors_module_init(); 通過JNI調用本地架構,得到SensorService,SensorService初始化控制流程各功能。
new Sensor(); 建立一個Sensor對象,可查閱官網API android.hardware.Sensor
sensors_module_get_next_sensor(); 上層得到裝置支援的所有Sensor,並放入SensorList鏈表。
new SensorThread(); 建立Sensor線程,當應用程式registerListener()註冊監聽器的時候開啟線程run(),注意當沒有資料變化時,線程會阻塞。
站在上層的角度,我們看不到SensorManager做了兩件重要的工作,即
1) 得到本地架構SensorManager.cpp,獲得Sensor真正的後台服務SensorService
2) 建立EventQueue用來管理資料,這個是4.0新版本的一大變化,這個變化,導致抽象層有關資料流的內容全部重寫...
3 本地架構
為了不陷入茫茫的代碼海洋,這裡簡單的做個總結,
SensorManager負責控制流程,通過C/S binder機制與SensorService通訊。
SensorEventQueue負責資料流,通過管道機制讀寫底層資料。
SensorSevice把任務交給SensorDevice,SensorDevice調用標準的抽象層介面。
Sensor架構的抽象層介面是最標準的一種,它很好的實現了抽象層與本地架構的分離。
當然還有其它類型的抽象層介面,這裡不作討論。
本文轉載於:http://blog.csdn.net/qianjin0703/article/details/7568641
==================================================================================================
作者:歐陽鵬 歡迎轉載,與人分享是進步的源泉!
轉載請保留原文地址:http://blog.csdn.net/ouyang_peng
==================================================================================================