編輯:Android開發實例
讓我們來看看SensorManager的代碼
SensorManager框架層代碼
@frameworks/base/core/java/android/hardware/SensorManager.java
- public SensorManager(Looper mainLooper) {
- mMainLooper = mainLooper; // 上面說了,這是Activity的Looper
- synchronized(sListeners) {
- if(!sSensorModuleInitialized) {
- sSensorModuleInitialized = true;
- nativeClassInit(); // 好像是調用本地方法初始化
- sWindowManager = IWindowManager.Stub.asInterface(
- ServiceManager.getService("window")); // 獲得Windows服務,不管它
- if (sWindowManager != null) {
- // if it's null we're running in the system process
- // which won't get the rotated values
- try {
- sRotation = sWindowManager.watchRotation(
- newIRotationWatcher.Stub() {
- public voidonRotationChanged(int rotation) {
- SensorManager.this.onRotationChanged(rotation);
- }
- }
- );
- } catch (RemoteException e) {
- }
- }
- // initialize the sensor list
- sensors_module_init(); // 初始化sensor module
- final ArrayList<Sensor> fullList = sFullSensorsList; // SensorManager維護的Sensor列表
- int i = 0;
- do {
- Sensor sensor = new Sensor(); // 創建sensor對象,這個是傳遞給App的哦
- //調用module的方法,獲得每一個sensor設備
- i = sensors_module_get_next_sensor(sensor, i);
- if (i>=0) {
- //Log.d(TAG, "found sensor: " + sensor.getName() +
- // ", handle=" +sensor.getHandle());
- sensor.setLegacyType(getLegacySensorType(sensor.getType()));
- fullList.add(sensor); // 添加到SM維護的Sensor列表(嘿嘿)
- sHandleToSensor.append(sensor.getHandle(), sensor);
- }
- }while (i>0);
- sPool= new SensorEventPool( sFullSensorsList.size()*2 );
- sSensorThread = new SensorThread(); // 喲,創建線程了好像
- }
- }
- }
很明顯nativeClassInit(),sensors_module_init(),sensors_module_get_next_sensor()都是本地實現的方法。
- private static native void nativeClassInit();
- private static native int sensors_module_init();
- private static native intsensors_module_get_next_sensor(Sensor sensor, int next);
根據之前看代碼的經驗可知,很可能在frameworks/base/core/對應一個jni目錄下的存在其對應的本地代碼:
- frameworks/base/core/java/android/hardware/SensorManager.java
- frameworks/base/core/jni/android_hardware_SensorManager.cpp
果不其然,在jni存在其本地代碼,讓我們來看下nativeClassInit函數:
@frameworks/base/core/jni/android_hardware_SensorManager.cpp
- static void
- nativeClassInit (JNIEnv *_env, jclass _this)
- {
- jclasssensorClass = _env->FindClass("android/hardware/Sensor");
- SensorOffsets& sensorOffsets = gSensorOffsets;
- sensorOffsets.name =_env->GetFieldID(sensorClass, "mName", "Ljava/lang/String;");
- sensorOffsets.vendor =_env->GetFieldID(sensorClass, "mVendor", "Ljava/lang/String;");
- sensorOffsets.version =_env->GetFieldID(sensorClass, "mVersion", "I");
- sensorOffsets.handle =_env->GetFieldID(sensorClass, "mHandle", "I");
- sensorOffsets.type = _env->GetFieldID(sensorClass,"mType", "I");
- sensorOffsets.range =_env->GetFieldID(sensorClass, "mMaxRange", "F");
- sensorOffsets.resolution =_env->GetFieldID(sensorClass, "mResolution","F");
- sensorOffsets.power =_env->GetFieldID(sensorClass, "mPower", "F");
- sensorOffsets.minDelay =_env->GetFieldID(sensorClass, "mMinDelay", "I");
- }
其代碼比較簡單,將Java框架層的Sensor類中的成員保存在本地代碼中的gSensorOffsets 結構體中將來使用。
sensors_module_init()本地方法的實現:
- static jint
- sensors_module_ini(JNIEnv *env, jclass clazz)
- {
- SensorManager::getInstance();
- return 0;
- }
在本地代碼中調用了SensorManager的getInstance方法,這又是一個典型的單例模式獲得類的對象,注意這兒的SensorManager是本地的類,而不是Java層的SensorManager類。
本地SensorManager的定義
@frameworks/base/include/gui/SensorManager.h
- class SensorManager :
- publicASensorManager,
- publicSingleton<SensorManager>
- {
- public:
- SensorManager();
- ~SensorManager();
- ssize_tgetSensorList(Sensor const* const** list) const;
- Sensor const*getDefaultSensor(int type);
- sp<SensorEventQueue> createEventQueue();
- private:
- //DeathRecipient interface
- voidsensorManagerDied();
- status_tassertStateLocked() const;
- private:
- mutable MutexmLock;
- mutablesp<ISensorServer> mSensorServer;
- mutableSensor const** mSensorList;
- mutableVector<Sensor> mSensors;
- mutablesp<IBinder::DeathRecipient> mDeathObserver;
- };
注意SensorManager又繼承了ASensorManager和泛型類Singleton<SensorManager>,而SensorManager類定義裡沒有getInstance所以其定義肯定是在ASensorManager或Singleton中。
@frameworks/base/include/utils/Singleton.h
- template <typename TYPE>
- class ANDROID_API Singleton
- {
- public:
- staticTYPE& getInstance() {
- Mutex::Autolock _l(sLock);
- TYPE*instance = sInstance;
- if(instance == 0) {
- instance = new TYPE();
- sInstance = instance;
- }
- return*instance;
- }
- static boolhasInstance() {
- Mutex::Autolock _l(sLock);
- returnsInstance != 0;
- }
- protected:
- ~Singleton(){ };
- Singleton() {};
- private:
- Singleton(const Singleton&);
- Singleton& operator = (const Singleton&);
- static MutexsLock;
- static TYPE*sInstance;
- };
- //---------------------------------------------------------------------------
- }; // namespace android
第一次調用getInstance方法時,創建泛型對象即:SensorManager,隨後再調用該方法時返回第一次創建的泛型對象。
本地SensorManager是一個單例模式,其構造方法相對比較簡單,它的主要工作交給了assertStateLocked方法:
@frameworks/base/libs/gui/SensorManager.cpp
- SensorManager::SensorManager()
- :mSensorList(0)
- {
- // okay we'renot locked here, but it's not needed during construction
- assertStateLocked();
- }
- status_t SensorManager::assertStateLocked() const {
- if(mSensorServer == NULL) {
- // try for one second
- constString16 name("sensorservice");
- for (inti=0 ; i<4 ; i++) {
- status_t err = getService(name,&mSensorServer);
- if(err == NAME_NOT_FOUND) {
- usleep(250000);
- continue;
- }
- if(err != NO_ERROR) {
- return err;
- }
- break;
- }
- classDeathObserver : public IBinder::DeathRecipient {
- SensorManager& mSensorManger;
- virtual void binderDied(const wp<IBinder>& who) {
- LOGW("sensorservice died [%p]", who.unsafe_get());
- mSensorManger.sensorManagerDied();
- }
- public:
- DeathObserver(SensorManager& mgr) : mSensorManger(mgr) { }
- };
- mDeathObserver = new DeathObserver(*const_cast<SensorManager*>(this));
- mSensorServer->asBinder()->linkToDeath(mDeathObserver);
- mSensors= mSensorServer->getSensorList();
- size_tcount = mSensors.size();
- mSensorList = (Sensor const**)malloc(count * sizeof(Sensor*));
- for(size_t i=0 ; i<count ; i++) {
- mSensorList[i] = mSensors.array() + i;
- }
- }
- returnNO_ERROR;
- }
在assertStateLocked方法裡,先通過getService獲得SensorService對象,然後注冊了對SensorService的死亡監聽器,SensorManager與SensorService不求同年同月同日,只求同年同月同日死。拜完了兄弟之後,調用getSensorList得到所有傳感器的對象,存放到mSensorList中,保存在本地空間裡。
在上面函數調用中首先調用getService來獲得SensorService服務,然後執行mSensorServer->getSensorList來獲得服務提供的傳感器列表:
- Vector<Sensor> SensorService::getSensorList()
- {
- return mUserSensorList;
- }
大家要注意啊,上面的getSensorList函數只是返回了mUserSensorList,而這個變量是在什麼時候初始化的呢?
根據2.1節可知,SensorService在本地被初始化時,構造函數裡並沒有對mUserSensorList進行初始化,而SensorService裡有一個onFirstRef方法,這個方法當SensorService第一次被強引用時被自動調用。那SensorService第一次被強引用是在什麼時候呢?
在SensorManager::assertStateLocked方法裡調用getService獲得SensorService保存到mSensorServer成員變量中。
mSensorServer的定義在frameworks/base/include/gui/SensorManager.h中:
- class SensorManager :
- public ASensorManager,
- public Singleton<SensorManager>
- {
- mutable sp<ISensorServer>mSensorServer;
- mutable Sensorconst** mSensorList;
- mutable Vector<Sensor> mSensors;
- };
可以看出mSensroServer為強引用類型。所以在創建本地中的SensorManager類對象時,自動強引用SensorService,自動調用onFirstRef方法:
@frameworks/base/services/sensorservice/SensorService.cpp的onFirstRef簡化方法如下:
- void SensorService::onFirstRef()
- {
- LOGD("nuSensorService starting...");
- SensorDevice& dev(SensorDevice::getInstance()); //創建SensorDevice對象dev
- if(dev.initCheck() == NO_ERROR) {
- sensor_tconst* list;
- ssize_tcount = dev.getSensorList(&list); //獲得傳感器設備列表
- if (count> 0) {
- …
- for(ssize_t i=0 ; i<count ; i++) {
- registerSensor( new HardwareSensor(list[i]) ); // 注冊在本地獲得的傳感器
- …
- }
- constSensorFusion& fusion(SensorFusion::getInstance());
- if(hasGyro) { // 如果有陀螺儀設備,則先注冊和陀螺儀有關的虛擬傳感器設備
- registerVirtualSensor( newRotationVectorSensor() ); // 虛擬旋轉傳感器
- registerVirtualSensor( new GravitySensor(list, count) ); // 虛擬重力傳感器
- registerVirtualSensor( new LinearAccelerationSensor(list, count) ); // 虛擬加速器
- // these are optional
- registerVirtualSensor( new OrientationSensor() ); // 虛擬方向傳感器
- registerVirtualSensor( new CorrectedGyroSensor(list, count) ); // 真正陀螺儀
- // virtual debugging sensors...
- char value[PROPERTY_VALUE_MAX];
- property_get("debug.sensors", value, "0");
- if (atoi(value)) {
- registerVirtualSensor( new GyroDriftSensor() ); // 虛擬陀螺測漂傳感器
- }
- }
- // build the sensor list returned tousers
- mUserSensorList = mSensorList;
- if(hasGyro &&
- (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR))) {
- // if we have the fancy sensor fusion, and it's not provided by the
- // HAL, use our own (fused) orientation sensor by removing the
- // HAL supplied one form the user list.
- if (orientationIndex >= 0) {
- mUserSensorList.removeItemsAt(orientationIndex);
- }
- }
- run("SensorService",PRIORITY_URGENT_DISPLAY);
- mInitCheck = NO_ERROR;
- }
- }
- }
上面代碼首先通過SensorDevice::getInstance()創建對象dev,調用dev.getSensorList(&list)獲得傳感器列表,將取出的sensor_t類型list傳感器列表,塑造了HardwareSensor對象,傳遞給了registerSensor方法,通過registerSensor注冊傳感器,然後通過單例模型創建了SensorFusion對象,創建並注冊了一系列的虛擬傳感器,疑惑,極大的疑惑,怎麼傳感器還有虛擬的??其實你注意看這幾個傳感器最前面的條件,if(hasGyro),表示如果存在陀螺儀的話,會創建這些虛擬設備,再看這些虛擬設備:旋轉,重力,加速器,方向等,這些設備都對應一個物理硬件:陀螺儀,所以這些邏輯上存在,物理上不存在的設備叫虛擬設備。在初始化了虛擬設備後,將mSensorList傳感器列表賦值給mUserSensorList,mSensorList是由registerSensor初始化的,mUserSensorList是要提交給Java框架層的傳感器列表,最後通過run方法運行了SensorService線程,我們先來看下registerSensor的代碼:
- void SensorService::registerSensor(SensorInterface* s)
- {
- sensors_event_t event;
- memset(&event,0, sizeof(event));
- const Sensorsensor(s->getSensor());
- // add to thesensor list (returned to clients)
- mSensorList.add(sensor);
- // add to ourhandle->SensorInterface mapping
- mSensorMap.add(sensor.getHandle(), s);
- // create anentry in the mLastEventSeen array
- mLastEventSeen.add(sensor.getHandle(), event);
- }
通過分析上面代碼可知,將傳入的HardwareSensor對象塑造了Sensor,添加到mSensorList向量表裡,然後將HardwareSensor對象添加到mSensroMap鍵值對裡,將新建的傳感器事件數據封裝對象event添加到mLastEventSeen鍵值對中。
我們通過下面的時序圖來看下Sensor列表的獲取過程。
讓我們再來看看SensorService線程,還記得前面SensorService的父類中有一個Thread類,當調用run方法時會創建線程並調用threadLoop方法。
- bool SensorService::threadLoop()
- {
- LOGD("nuSensorService thread starting...");
- const size_tnumEventMax = 16 * (1 + mVirtualSensorList.size());
- sensors_event_t buffer[numEventMax];
- sensors_event_t scratch[numEventMax];
- SensorDevice& device(SensorDevice::getInstance());
- const size_tvcount = mVirtualSensorList.size();
- ssize_tcount;
- do {
- // 調用SensorDevice的poll方法看樣子要多路監聽了
- count = device.poll(buffer,numEventMax);
- if(count<0) {
- LOGE("sensor poll failed (%s)", strerror(-count));
- break;
- }
- // 記錄poll返回的每一個傳感器中的最後一個數據信息到mLastEventSeen中
- recordLastValue(buffer, count);
- // handlevirtual sensors 處理虛擬傳感器數據
- if (count&& vcount) {
- sensors_event_t const * const event = buffer;
- // 獲得虛擬傳感器列表
- constDefaultKeyedVector<int, SensorInterface*> virtualSensors(
- getActiveVirtualSensors());
- constsize_t activeVirtualSensorCount = virtualSensors.size(); // 虛擬傳感器個數
- if(activeVirtualSensorCount) {
- size_t k = 0;
- SensorFusion& fusion(SensorFusion::getInstance());
- if (fusion.isEnabled()) {
- for (size_t i=0 ; i<size_t(count) ; i++) {
- fusion.process(event[i]); //處理虛擬傳感器設備事件
- }
- }
- for (size_t i=0 ; i<size_t(count) ; i++) {
- for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
- sensors_event_t out;
- if (virtualSensors.valueAt(j)->process(&out, event[i])) {
- buffer[count + k] =out;
- k++;
- }
- }
- }
- if (k) {
- // record the last synthesized values
- recordLastValue(&buffer[count], k);
- count += k;
- // sort the buffer by time-stamps
- sortEventBuffer(buffer, count);
- }
- }
- }
- // sendour events to clients...
- // 獲得傳感器連接對象列表
- constSortedVector< wp<SensorEventConnection> > activeConnections(
- getActiveConnections());
- size_tnumConnections = activeConnections.size();
- for(size_t i=0 ; i<numConnections ; i++) {
- sp<SensorEventConnection> connection(
- activeConnections[i].promote());
- if(connection != 0) {
- // 向指定的傳感器連接客戶端發送傳感器數據信息
- connection->sendEvents(buffer, count, scratch);
- }
- }
- } while (count>= 0 || Thread::exitPending()); // 傳感器循環監聽線程
- LOGW("Exiting SensorService::threadLoop => aborting...");
- abort();
- return false;
- }
我們看到device.poll方法,阻塞在了SensorDevice的poll方法上,它肯定就是讀取Sensor硬件上的數據了,將傳感器數據保存在buff中,然後調用recordLastValue方法,只保存同一類型傳感器的最新數據(最後采集的一組數據)到鍵值對象mLastEventSeen裡對應傳感器的值域中。如果傳感器設備是虛擬設備則調用SensorFusion.Process()方法對虛擬設備數據進行處理。SensorFusion關聯一個SensorDevice,它是虛擬傳感器設備的一個加工類,負責虛擬傳感器數據的計算、處理、設備激活、設置延遲、獲得功耗信息等操作。
讓我們來回顧下整個過程吧。
1. SensorManager對象創建並調用assertStateLocked方法
2. 在assertStateLocked方法中調用getService,獲得SensorService服務
3. 當SensorService第一次強引用時,自動調用OnFirstRef方法
4.獲得SensorDevice單例對象
6. 調用SensorDevice.getSensorList方法sensor_t列表保存在SensorService中
8. 調用registerSensor注冊傳感器,添加到mSensorList列表中
9. 啟動SensorService線程,准備監聽所有注冊的傳感器設備
12. 多路監聽注冊的傳感器設備,當有傳感器事件時,返回sensor_event_t封裝的事件信息
16. 記錄產生傳感器事件的設備信息
17. 調用getActiveConnections獲得所有的活動的客戶端SensorEventConnection類對象
19.向客戶端發送傳感器事件信息
轉自:http://blog.csdn.net/mr_raptor/article/details/8128912
前面文章講解了Android的藍牙基本用法,本文講得深入些,探討下藍牙方面的隱藏API。用過Android系統設置(Setting)的人都知道藍牙搜索之後可以建立
在android開發的過程中我們經常因為沒有好的美工圖片失真,這樣使界面看起來要遜色很多,有的時候可能我們會想在drawable-hdpi,ldpi,mdpi下放
可以顯示在的Android任務,通過加載進度條的進展。進度條有兩種形狀。加載欄和加載微調(spinner)。在本章中,我們將討論微調(spinner)。Spinner 用
學習目的: 1、掌握在Android中如何建立Button 2、掌握Button的常用屬性 3、掌握Button按鈕的點擊事件(監聽器) Button是各種UI中